Привёл набор capabilities в OpenSpec к цепочке обработки, чтобы имя capability отвечало одному поведению. Чисто по спекам, код и поведение системы не меняются. Change refactor-capability-boundaries (архивирован): - recognition разделён на recognition (разбор LLM) + metadata-match (сверка с базами) - review выделен из web-ui + мигрирован из docs/specs/review-ux.md - новые capability из docs/specs: file-layout, download-tracking, notifications - identity очищен до инфра-id; приём (инфохэши, дедуп, ядро приёма) — в ingest - уведомление о рассинхроне перенесено из state-reconciliation в notifications - дубль владения путём и безопасного undo оставлен в state-reconciliation Итог: 11 capabilities, openspec validate --strict проходит (+37/−11 требований). Источник истины по мигрированным темам переехал в openspec/specs (шапки в docs). Снят пункт беклога «Пересмотр набора capabilities». Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
7.9 KiB
ADDED Requirements
Requirement: Пред-парс имени релиза
Перед вызовом LLM система SHALL выполнять дешёвый пред-парс имени торрента
(go-ptn): извлекать черновые название, год, сезон, серию и качество. Результат
пред-парса SHALL использоваться как вспомогательный сигнал в промпте и как
сторона проверки согласованности при решении auto/review, но НЕ SHALL считаться
итоговым распознаванием.
Scenario: Пред-парс даёт черновые поля
- WHEN на вход распознавания поступает имя релиза
Fargo.S02.2015.WEB-DL.1080p - THEN пред-парс возвращает черновые
title,year,season,quality - AND эти значения передаются в промпт LLM как подсказка
Requirement: Разбор сигналов LLM в структурированный план
Система SHALL передавать LLM недоверенные сигналы (имя торрента, дерево файлов с
размерами, текстовый контекст и накопленные подсказки, пред-парс) и получать
структурированный план в схеме: type (movie|series), title,
original_title, year, provider_hint, files[] и confidence. Каждый
элемент files[] SHALL нести src, role
(main|episode|subtitle|extra|sample|ignore) и, для сериала,
per-file season/episode (отдельного скалярного season быть SHALL NOT — так
выражаются мультисезонные паки и спецвыпуски). План SHALL приниматься только
если каждый files[].src совпадает с реальным файлом торрента.
Scenario: План сериала с per-file нумерацией
- GIVEN сезон-пак из 10 видеофайлов
- WHEN LLM возвращает план
- THEN
type=series, а каждый видеофайл несёт своиseason/episode
Scenario: Несуществующий src отклоняется
- GIVEN ответ LLM, где
files[].srcне совпадает ни с одним файлом торрента - WHEN план разбирается
- THEN такой план не принимается как валидный
Requirement: Провайдер LLM за абстракцией со структурированным выводом
Доступ к LLM SHALL быть за интерфейсом с выбором реализации по полю [llm].type
(первый тип — openai-compat). Система SHALL запрашивать JSON-режим
(response_format: {"type":"json_object"}), срезать ```-ограждения и
валидировать ответ в Go против схемы плана. При ошибке разбора система SHALL
ретраить до [llm].max_retries, передавая модели саму ошибку и схему. Если после
ретраев ответ не разобран, задача SHALL уходить в review (НЕ в failed) с
причиной «ответ LLM не разобран».
Scenario: Неразобранный ответ уходит в review
- GIVEN LLM, чей ответ не проходит валидацию схемы после всех ретраев
- WHEN завершается распознавание
- THEN задача переходит в
reviewс причиной «ответ LLM не разобран» - AND задача НЕ переходит в
failed
Requirement: Модель уверенности и решение auto/review
Система SHALL раскладывать автоматически (без review) только при выполнении
ВСЕГО: (1) подтверждённый единичный сильный матч в базе (metadata-match) с
provider_id; (2) структурная валидация без предупреждений (фильм — ровно один
основной видеофайл; сериал — число серий бьётся с базой, нумерация S·E
консистентна); (3) согласованность пред-парса и LLM по типу/названию/году. Иначе
задача SHALL уходить в review с явной причиной. Самооценку LLM (confidence)
система SHALL учитывать лишь как вспомогательный сигнал, НЕ как единственный гейт.
Scenario: Нет матча в базе — всегда review
- GIVEN план без подтверждённого матча в базе (база выключена или матча нет)
- WHEN принимается решение auto/review
- THEN задача уходит в
review, авто-раскладка не делается
Scenario: Матч и чистая валидация — авто
- GIVEN подтверждённый единичный матч, чистая структурная валидация и согласованность сигналов
- WHEN принимается решение
- THEN допускается авто-раскладка (при отсутствии
force_review)
Requirement: Роли файлов на краях раздачи
Система SHALL относить семплы, «экстра» и мусор к роли ignore (эвристики размер/
имя + LLM), а внешние субтитры (.srt, .ass, пары VobSub .idx+.sub) —
привязывать к соответствующему видео. Любую неоднозначность нумерации (дыры,
дубли, спорные спецвыпуски) система SHALL эскалировать в review, а не разрешать
молча.
Scenario: Семпл помечается ignore
- GIVEN раздача с файлом
sample.mkvмалого размера - WHEN строится план
- THEN этот файл получает роль
ignoreи в раскладку не попадает
REMOVED Requirements
Requirement: Сверка с базой по нескольким названиям
Reason: Работа с внешними базами метаданных — отдельное поведение; выделена в
capability metadata-match.
Migration: Требование перенесено без изменений в metadata-match (см.
specs/metadata-match).
Requirement: Локаль запроса к TMDB
Reason: Относится к работе с метабазой (TMDB), выделенной в metadata-match.
Migration: Требование перенесено без изменений в metadata-match.
Requirement: Нормализация названий при сравнении
Reason: Нормализация — часть сверки с метабазой, выделенной в metadata-match.
Migration: Требование перенесено без изменений в metadata-match.
Requirement: Кандидат несёт URL для внешней проверки
Reason: Кандидат — сущность метабазы; контракт кандидата относится к
metadata-match.
Migration: Требование перенесено без изменений в metadata-match.