раскладка av-dev повышена с канона 12 до версии 5
- три плагина слились в один `av-dev`: служебные `docs/.docs.json` и `tasks/.tasks.json` заменены на `.av-dev.toml` в корне, в гейте переехали пути трёх скриптов, вызовы скиллов переименованы по всему репозиторию - тип задачи `goal` и `ROADMAP.md` упразднены: семь целей закрыты с причинами, теги сняты, объявлена стадия `support` - метка `small`/`medium`/`large` снята из процесса — вместо «Триггеров метки» в review.md подраздел «Когда звать глубокое ревью»; следом разобран урожай doc-consistency: девять фактов сведены к одному дому
This commit is contained in:
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"tasks": 1
|
||||
}
|
||||
+15
-6
@@ -1,12 +1,21 @@
|
||||
# Беклог
|
||||
|
||||
Что **можно взять**. Одна задача = один файл `items/<slug>.md`
|
||||
+ строка здесь. Целей тут нет — они в [ROADMAP.md](ROADMAP.md): беклог — то, что
|
||||
берут, роадмап — то, подо что берут. Ведётся скиллом `av-dev-tasks:tasks`.
|
||||
+ строка здесь. Ведётся скиллом `av-dev:task-track`.
|
||||
|
||||
**Порядок строк внутри секции — это приоритет.** Первая строка секции — то, что
|
||||
делают следующим. Порядок назначает человек на груминге
|
||||
(`av-dev-tasks:groom`), машина его не выводит.
|
||||
<!-- стадия -->
|
||||
Стадия проекта — **доработка** (`[tasks] stage = "support"`).
|
||||
**Порядок строк внутри секции — важность:** первая строка это то,
|
||||
что делают следующим. Назначает его человек на груминге, машина не
|
||||
выводит. Секции — полки домена, смысла они не несут. Заводится по
|
||||
одной, по мере появления; пустой беклог — нормальное состояние.
|
||||
<!-- /стадия -->
|
||||
|
||||
Одно место в очереди назначено не человеком, а типом: сырьё (`research` без
|
||||
раздела «Вопрос») стоит в конце секции — его не берут.
|
||||
|
||||
Тип записи стоит первым полем меты и решает, что у неё может быть:
|
||||
✨ `feature` 🐞 `fix` 🧹 `chore` 🔬 `research`
|
||||
|
||||
Секции «блокеры» здесь нет и не заводится: блокер — это состояние, оно живёт до
|
||||
ответа человека, а его следы — вопросами в файлах задач.
|
||||
@@ -41,7 +50,7 @@
|
||||
## Инфраструктура
|
||||
|
||||
- [🐞 Тормозить опрос qBittorrent бэкоффом при недоступности и эскалировать устойчивый сбой](items/background-error-noise.md) — недоступный qBittorrent опрашивается каждые 5 с и даёт WARN на каждом тике: нужен экспоненциальный бэкофф до минутного потолка со сбросом по первому успеху и ERROR на устойчивой деградации
|
||||
- [🧹 Откалибровать проходы ревью и завести ревьювер наименований](items/quality-review-agents.md) — конвейер ревью переехал в плагин `av-dev-pipeline`; осталась калибровка проходов на этом проекте и ревьювер наименований (ждёт словарь единого языка)
|
||||
- [🧹 Откалибровать проходы ревью и завести ревьювер наименований](items/quality-review-agents.md) — конвейер ревью переехал в плагин `av-dev`; осталась калибровка проходов на этом проекте и ревьювер наименований (ждёт словарь единого языка)
|
||||
- [✨ Закрыть веб-UI авторизацией, когда доверенной LAN станет мало](items/web-ui-auth.md) — для v1 решено без авторизации (доверенная LAN, опц. allowlist подсетей) — задел на случай, если понадобится защита
|
||||
- [🧹 Бэкапить SQLite по расписанию с ротацией](items/sqlite-backup.md) — architecture требует бекапить data-том, но стратегия не описана — сбой или редеплой стирают всё in-flight состояние (проще, пока БД маленькая)
|
||||
- [✨ Проверять в healthcheck доступность qBittorrent, LLM и метабаз и показывать её в UI](items/deep-healthcheck-dependencies.md) — /healthz проверяет только сам сервис — недоступность qBittorrent/LLM/метабазы видна лишь по застрявшим задачам, нет readiness и бейджа в UI
|
||||
|
||||
@@ -7,3 +7,10 @@
|
||||
<!-- - ГГГГ-ММ-ДД `slug` — Заголовок. Причина: … Была секция: … -->
|
||||
- 2026-08-06 `learn-from-user-corrections` — ✨ Подмешивать прошлые правки человека в промпт распознавания (few-shot). Причина: решено не собирать базу правок человека: направление — тюнинг автоматического распознавания без участия человека. Была секция: ядро продукта.
|
||||
- 2026-08-06 `recognition-eval-harness` — 🧹 Завести eval-харнес распознавания: корпус кейсов и метрику точности. Причина: решено не собирать размеченный корпус руками: направление — тюнинг автоматического распознавания без участия человека. Была секция: инфраструктура.
|
||||
- 2026-09-02 `recognition-accuracy` — 🎯 Раздача узнаётся верно без подсказок человека. Причина: тип goal упразднён каноном раскладки 3; зонтик над точностью распознавания снят, работы живут строками беклога сами (tvdb-search-response-live-check, auto-link-confidence-gate, multi-pass-verification, candidate-match-strength, guessit-sidecar). Была секция: Направления.
|
||||
- 2026-09-02 `complex-releases` — 🎯 Раскладывается не только типовая раздача. Причина: тип goal упразднён каноном раскладки 3; зонтик над нетиповыми раздачами снят, работы живут строками беклога сами (anime-absolute-numbering, disc-image-releases, merge-incremental-redownload, external-subtitles, naming-edge-cases, complex-series-releases, episode-numbering-canon, title-versions-repacks). Была секция: Направления.
|
||||
- 2026-09-02 `ingest-and-review-interfaces` — 🎯 Раздача приносится и подтверждается из любого транспорта. Причина: тип goal упразднён каноном раскладки 3; зонтик над приёмом и ревью снят, работы живут строками беклога сами (torrent-url-fetch, review-mapping-editor, notification-source-binding, sse-live-updates, web-ui-pwa, web-ui-auth, telegram-messages-audit, completion-webhook). Была секция: Направления.
|
||||
- 2026-09-02 `state-integrity` — 🎯 По записи загрузки видно, как она сюда попала. Причина: тип goal упразднён каноном раскладки 3; зонтик над целостностью состояния снят, работы живут строками беклога сами (delete-checks-active-infohash-owner, delete-leaves-stale-done, download-transition-history, infohash-identity-integrity). Была секция: Направления.
|
||||
- 2026-09-02 `operational-resilience` — 🎯 Сервис переживает рост и потерю тома. Причина: тип goal упразднён каноном раскладки 3; зонтик над эксплуатационной устойчивостью снят, работы живут строками беклога сами (sqlite-backup, db-retention-cleanup, deep-healthcheck-dependencies, metadata-cache, free-space-check-copy-fallback, scale-100-downloads). Была секция: Сопровождение.
|
||||
- 2026-09-02 `dev-process-quality` — 🎯 Домен называется одинаково везде, ревью откалибровано. Причина: тип goal упразднён каноном раскладки 3; зонтик над качеством процесса снят, работы живут строками беклога сами (ubiquitous-language-glossary, quality-review-agents, tests-convention, convention-candidates). Была секция: Сопровождение.
|
||||
- 2026-09-02 `bulk-download-management` — 🎯 Загрузки удаляются пачкой, а не по одной. Причина: тип goal упразднён каноном раскладки 3; групповое удаление раздач в беклог не берётся — по решению человека при повышении раскладки заводится заново, когда уборка десятка раздач станет болью. Была секция: Направления.
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
# Роадмап
|
||||
|
||||
Что приложение уже умеет и чего ещё не умеет. Цель — файл типа `goal` в
|
||||
`items/`; её задачи здесь **не перечисляются** — перечень даёт
|
||||
`tasks.py list --goal <слаг>`. В `Запланировано` очередь значима и
|
||||
обосновывается прозой; в `Направлениях` порядка нет; `Сопровождение` — то, чем
|
||||
держат проект, а не возможности приложения; в `Готово` строку с датой пишет
|
||||
`close --implemented`.
|
||||
|
||||
## Запланировано
|
||||
|
||||
Пусто. Фазы Ф0–Ф6 прежней дорожной карты (каркас, приём и трекинг,
|
||||
распознавание, раскладка и ревью, метаданные, Telegram и UX, деплой) закрыты —
|
||||
сквозной путь работает и развёрнут; закрытый шаг планом больше не является.
|
||||
Следующая упорядоченная очередь появится, когда она понадобится.
|
||||
|
||||
## Направления
|
||||
|
||||
- [🎯 Раздача узнаётся верно без подсказок человека](items/recognition-accuracy.md) — распознавание ошибается молча и правдоподобно, а смена модели или правка промпта идёт вслепую — сдвига точности не видно ни до, ни после
|
||||
- [🎯 Раскладывается не только типовая раздача](items/complex-releases.md) — типовая раздача раскладывается, а всё, что сложнее одного сезона одного тайтла, упирается в ручной разбор
|
||||
- [🎯 Раздача приносится и подтверждается из любого транспорта](items/ingest-and-review-interfaces.md) — путь «принести раздачу и подтвердить догадку» упирается в незакрытые куски интерфейсов, а не в логику
|
||||
- [🎯 По записи загрузки видно, как она сюда попала](items/state-integrity.md) — известные окна рассинхрона и потери маркеров: каждое по отдельности самоисцеляется, вместе — источник необъяснимых состояний
|
||||
- [🎯 Загрузки удаляются пачкой, а не по одной](items/bulk-download-management.md) — удаление раздачи с файлами доступно только по одной кнопке на странице одной загрузки — уборка десятка раздач превращается в десяток заходов
|
||||
|
||||
## Сопровождение
|
||||
|
||||
- [🎯 Сервис переживает рост и потерю тома](items/operational-resilience.md) — сервис работает, но не переживает роста: база копится вечно, бэкапа нет, отказ зависимости виден только по застрявшим задачам
|
||||
- [🎯 Домен называется одинаково везде, ревью откалибровано](items/dev-process-quality.md) — наименования домена расходятся между спеками, UI и кодом, а конвейер ревью не откалиброван — растёт цена каждой следующей задачи
|
||||
|
||||
## Готово
|
||||
|
||||
Пусто. Фазы Ф0–Ф6 велись прозой и целями в роадмапе не числились, поэтому
|
||||
строк с датами за ними нет; что было сделано и когда — по архиву
|
||||
`openspec/changes/archive/`. Первую строку сюда впишет `close --implemented`
|
||||
на первой достигнутой цели.
|
||||
@@ -3,7 +3,6 @@
|
||||
- **Тип:** feature
|
||||
- **Категория:** Ядро продукта — уступила верх четырём мелочам с готовыми оракулами: сама задача жива и остаётся первой фичей ядра, но стоит дороже и в ближайший заход не влезает
|
||||
- **Зачем:** аниме со сквозной нумерацией (#137) не раскладывается в SxxEyy, который ждёт Jellyfin — нужен пересчёт абсолютной нумерации
|
||||
- **Теги:** goal:complex-releases
|
||||
|
||||
Релизы аниме часто нумеруют серии сквозным числом (#137) без сезонов, а Jellyfin ждёт SxxEyy. Нужен пересчёт абсолютной нумерации в сезон/серию — надёжнее всего через TVDB (там есть absolute order). Отдельный крайний случай распознавания; на стороне ревью — веб-хелпер «absolute → S·E».
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
- **Тип:** feature
|
||||
- **Категория:** Ядро продукта — тот же internal/recognize, что и первая задача — окно открыто; решение принято 2026-07-08, осталось снять пере-применение дефолта, понизить 0.85→0.7 и записать в спеку
|
||||
- **Зачем:** Решено (B): гейт оставляем как доп. проверку на ревью — выключаемый порог, дефолт 0.85→0.7, записать в спеку
|
||||
- **Теги:** goal:recognition-accuracy
|
||||
|
||||
Аудит спек↔код (2026-07-03) нашёл расхождение: спека recognition считает
|
||||
`confidence` вспомогательным сигналом (условия авто — только матч в базе +
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
# 🎯 Загрузки удаляются пачкой, а не по одной
|
||||
|
||||
- **Тип:** goal
|
||||
- **Секция:** Направления
|
||||
- **Зачем:** удаление раздачи с файлами доступно только по одной кнопке на странице одной загрузки — уборка десятка раздач превращается в десяток заходов
|
||||
|
||||
Ради чего: разложенные раздачи копятся, и убирают их обычно скопом — после
|
||||
просмотра сезона, при чистке диска, после серии неудачных заливок. Сегодня
|
||||
удаление живёт только в danger-секции страницы одной загрузки, поэтому уборка
|
||||
десяти раздач стоит десяти проходов «список → карточка → подтверждение».
|
||||
|
||||
При этом удаление с файлами необратимо: оно зовёт `torrents/delete` с
|
||||
`deleteFiles=true`, а гард последней копии там выключен сознательно
|
||||
(инвариант «Источник неприкосновенен», исключение 1). Групповой режим обязан
|
||||
сделать уборку дешевле, не сделав ошибку дешевле.
|
||||
|
||||
## Завершение
|
||||
|
||||
Достигнута, когда человек убирает любое число раздач одним проходом: выбирает
|
||||
их в списке, один раз подтверждает удаление по перечню, где каждая раздача
|
||||
названа поимённо, и видит поимённый результат — что снесено, что отказало и
|
||||
почему. Ни одна раздача не сносится без того, чтобы человек увидел её в
|
||||
подтверждении.
|
||||
@@ -3,7 +3,6 @@
|
||||
- **Тип:** research
|
||||
- **Категория:** Ядро продукта
|
||||
- **Зачем:** у кандидата метабазы нет метрики силы совпадения — список кандидатов на ревью нечем отсортировать по уверенности (сперва проработать процесс матчинга)
|
||||
- **Теги:** goal:recognition-accuracy
|
||||
|
||||
У кандидата метабазы нет метрики силы совпадения (metadata_candidate хранит provider/id/title/year/url), решение «авто vs review» — по правилу «единственный сильный матч + валидация», не по числу. Для ревью: список кандидатов нечем отсортировать/подсветить по уверенности. Идея — ввести на этапе матча силу совпадения кандидата (точное совпадение названия+года vs частичное) для сортировки и подсказки в UI. Шире — продумать сам процесс распознавания и матчинга: границы «разбор LLM / поиск в базе / сверка», что храним у кандидата, как считаем и показываем уверенность.
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
- **Тип:** research
|
||||
- **Категория:** Инфраструктура
|
||||
- **Зачем:** завершение сейчас ловим поллингом qBittorrent — webhook реагировал бы быстрее, но связывает нас с его конфигом (решим по опыту эксплуатации)
|
||||
- **Теги:** goal:ingest-and-review-interfaces
|
||||
|
||||
Сейчас завершение ловим поллингом qBittorrent раз в несколько секунд. Альтернатива: «Run external program on torrent completion» в qBittorrent дёргает эндпоинт jellybit. Реагирует быстрее, но связывает нас с конфигом qBittorrent.
|
||||
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
# 🎯 Раскладывается не только типовая раздача
|
||||
|
||||
- **Тип:** goal
|
||||
- **Секция:** Направления
|
||||
- **Зачем:** типовая раздача раскладывается, а всё, что сложнее одного сезона одного тайтла, упирается в ручной разбор
|
||||
- **Теги:** decomposed
|
||||
|
||||
Ради чего: сериальные паки, докачивание, аниме со сквозной нумерацией, образы дисков и внешние субтитры — это ровно тот контент, ради которого проект и заводился вместо arr-стека.
|
||||
|
||||
## Завершение
|
||||
|
||||
Достигнута, когда сериальный пак, докачивание недостающих серий, аниме со сквозной нумерацией, образ диска и внешние субтитры раскладываются без ручного вмешательства в файлы на диске — либо честно уходят в ревью с названной причиной, а не молча кладутся неверно.
|
||||
@@ -3,7 +3,6 @@
|
||||
- **Тип:** research
|
||||
- **Категория:** Ядро продукта
|
||||
- **Зачем:** сложные раздачи (все сезоны разом, паки, смешанная нумерация) целостно не проработаны — распознавание/ревью/раскладка заточены под один сезон
|
||||
- **Теги:** goal:complex-releases
|
||||
|
||||
Обычный случай — один сезон (его номер видно глазами и сверяем на ревью — под это сделана сводка сезонов). Но в редких заказах раздача сложнее: все сезоны сериала разом, пак нескольких сезонов, смешанная нумерация, вложенные папки сезонов, разнобойные имена файлов. Сейчас PlanFile.Season задаётся на каждом файле (мультисезон в принципе выразим), но целостно эти сценарии не проработаны: как надёжно распознать, как показать на ревью, как разложить и как стыкуется со сходимостью папки и merge-докачиванием. Решить, что поддерживаем явно, а что уводим в ревью как «сложную раскладку».
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
- **Тип:** research
|
||||
- **Категория:** Инфраструктура
|
||||
- **Зачем:** накоплен список кандидатов (внешние клиенты, конкурентность, тесты, CLI, время) — надо решить, что из них стало реальным трением, а что выдумано вперёд
|
||||
- **Теги:** goal:dev-process-quality
|
||||
|
||||
Список копился в черновике `docs/drafts/conventions-backlog.md` (удалён при
|
||||
переводе на канон, текст в истории git) под правилом «пишем по мере реального
|
||||
@@ -46,7 +45,7 @@
|
||||
- **Время.** Явный TZ всегда, хранение и логи в UTC. Уже частично в `CLAUDE.md`
|
||||
и `conventions/logging.md`, а `time.Now` вне `store` запрещён линтером — этот
|
||||
пункт, вероятно, закрыт и подлежит вычёркиванию.
|
||||
- **Язык вывода связан с мапперами.** Провенанс — ревью `tvdb-title-locale`
|
||||
- **Язык вывода связан с мапперами.** Откуда — ревью `tvdb-title-locale`
|
||||
(2026-08-07,
|
||||
[отчёт триажа](../../openspec/changes/archive/2026-08-07-tvdb-title-locale/review/report.md),
|
||||
находка R2 прохода `architecture`). Язык вывода живёт в пяти местах четырёх
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
- **Тип:** feature
|
||||
- **Категория:** Инфраструктура
|
||||
- **Зачем:** терминальные задачи и сырые ответы LLM копятся вечно — без авточистки список загрузок и БД деградируют по мере эксплуатации
|
||||
- **Теги:** goal:operational-resilience
|
||||
|
||||
Терминальные задачи (done/cancelled/failed/reverted), их попытки recognition с сырыми ответами LLM и metadata_candidate копятся вечно — БД и список загрузок распухают и становятся нечитаемыми. Нужна авточистка старше N дней (настройка в [storage] или [worker]) и/или ручное удаление. Маленькая задача, но без неё интерфейс деградирует по мере эксплуатации.
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
- **Тип:** feature
|
||||
- **Категория:** Инфраструктура
|
||||
- **Зачем:** /healthz проверяет только сам сервис — недоступность qBittorrent/LLM/метабазы видна лишь по застрявшим задачам, нет readiness и бейджа в UI
|
||||
- **Теги:** goal:operational-resilience
|
||||
|
||||
/healthz проверяет только сам сервис. Если qBittorrent, LLM или метабаза недоступны — узнаёшь лишь по застрявшим задачам. Нужна readiness-проверка ключевых зависимостей и отражение их состояния в UI (бейдж «qBittorrent недоступен»), чтобы причина простоя была видна сразу.
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
- **Тип:** fix
|
||||
- **Категория:** Ядро продукта
|
||||
- **Зачем:** удаление старой закрытой задачи уничтожает файлы живой загрузки с тем же инфохэшем; воспроизведено падающим тестом на ревью bulk-delete-page
|
||||
- **Теги:** goal:state-integrity
|
||||
|
||||
`Delete` зовёт `torrents/delete` с `deleteFiles=true` по хешам своей записи и не
|
||||
спрашивает, не владеет ли этим инфохэшем другая **активная** загрузка. Человек
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
- **Тип:** fix
|
||||
- **Категория:** Ядро продукта
|
||||
- **Зачем:** при недоступном qBittorrent задача весь простой соседа показывает done, хотя тайтла в Jellyfin уже нет: сверка падает на первом шаге и до коррекции не доходит
|
||||
- **Теги:** goal:state-integrity
|
||||
|
||||
`Delete` снимает библиотечные ссылки раньше, чем зовёт `qbt.Delete`. Если сосед
|
||||
недоступен, локальный шаг проходит, внешний падает, и задача остаётся в `done`.
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
# 🎯 Домен называется одинаково везде, ревью откалибровано
|
||||
|
||||
- **Тип:** goal
|
||||
- **Секция:** Сопровождение
|
||||
- **Зачем:** наименования домена расходятся между спеками, UI и кодом, а конвейер ревью не откалиброван — растёт цена каждой следующей задачи
|
||||
- **Теги:** decomposed
|
||||
|
||||
Ради чего: это не поведение продукта, а то, чем он делается. Единый словарь, калибровка проходов ревью и разбор накопленных кандидатов в конвенции — вложение в скорость всех остальных целей.
|
||||
|
||||
## Завершение
|
||||
|
||||
Достигнута, когда домен называется одинаково в спеках, коде и интерфейсе, а конвейер ревью откалиброван на журнале реальных дефектов, а не на догадках о том, что он ловит.
|
||||
@@ -3,7 +3,6 @@
|
||||
- **Тип:** feature
|
||||
- **Категория:** Ядро продукта
|
||||
- **Зачем:** раздача-образ Blu-ray разбирается пофайлово и едет в библиотеку россыпью .m2ts, а Jellyfin умеет такой каталог целиком
|
||||
- **Теги:** goal:complex-releases
|
||||
|
||||
Иногда для очень редкого фильма качается не один видеофайл, а полная копия
|
||||
диска — каталог `BDMV/` (Blu-ray) или `VIDEO_TS/` (DVD). Раскладка сегодня
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
- **Тип:** feature
|
||||
- **Категория:** Инфраструктура
|
||||
- **Зачем:** хранится только текущий статус загрузки — разбор «как сюда попали» идёт по логам сервера, нет таблицы истории переходов
|
||||
- **Теги:** goal:state-integrity
|
||||
|
||||
Сохранять полную историю переходов состояний загрузки (что/когда/почему/кто инициировал — воркер, человек, сверка), а не только текущее состояние. Сейчас по задаче виден лишь актуальный статус, разбор «как мы сюда попали» идёт по логам сервера. Отдельная таблица истории даёт лог переходов в карточке/расширенной информации и фундамент для метрик длительности стадий. Естественно ложится на собственный идентификатор загрузки и уже реализованный экран /download/{id}.
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
- **Тип:** research
|
||||
- **Категория:** Ядро продукта
|
||||
- **Зачем:** Косметика/редкость: порядок просмотра ок, но у тайтлов со спорным порядком (Бибоп) Jellyfin подтягивает не те подписи серий, если канон файлов ≠ дефолтный порядок провайдера тега
|
||||
- **Теги:** goal:complex-releases
|
||||
|
||||
Косметика и редкий случай: порядок просмотра не страдает (файлы уже
|
||||
пронумерованы канонически и лежат по порядку), разъезжаются только подписи серий
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
- **Тип:** feature
|
||||
- **Категория:** Ядро продукта
|
||||
- **Зачем:** Привязка субтитр→серия уже работает; остались пары VobSub .idx+.sub и потеря Lang/Flags
|
||||
- **Теги:** goal:complex-releases
|
||||
|
||||
Базовая привязка субтитр→серия для сериала уже работает: `layout.PlanFile` несёт
|
||||
`Season/Episode`, а `seriesDst` именует субтитр по стему эпизода
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
- **Тип:** feature
|
||||
- **Категория:** Ядро продукта
|
||||
- **Зачем:** copy-fallback при невозможности хардлинка может упереться в переполненный диск посреди раскладки — нет проверки места до копирования
|
||||
- **Теги:** goal:operational-resilience
|
||||
|
||||
Когда хардлинк невозможен (EXDEV/ENOTSUP/…), layout копирует файл, дублируя место на диске. На забитом диске это упрётся в полку посреди раскладки. Перед копированием проверять доступное место и при нехватке внятно уходить в failed с понятной причиной, а не падать на полпути.
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
- **Тип:** research
|
||||
- **Категория:** Ядро продукта
|
||||
- **Зачем:** go-ptn слабее питоновского guessit — если точности пред-парса не хватит, завернуть guessit в сервис-спутник рядом с бинарём
|
||||
- **Теги:** goal:recognition-accuracy
|
||||
|
||||
go-ptn слабее питоновского guessit. Если точности пред-парса не хватит — завернуть guessit в крошечный HTTP-сервис (один файл, поставляется рядом с бинарём jellybit) и спрашивать его на шаге пред-парса. Сохраняет «доставку копированием»: два файла вместо одного.
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
- **Тип:** research
|
||||
- **Категория:** Ядро продукта — сырьё, а не дефект: тело само не решает — «change по модели доверия/идентичности либо задокументировать как ограничение», и критерии приёмки писать не из чего; идёт на штурм, взять нельзя
|
||||
- **Зачем:** две находки ревью 2026-07-08 упираются в нерешённую модель идентичности: связывать ли v1- и v2-хеши одного торрента и что делать с парой xt, которую qBittorrent не подтверждал — merge, supersede или ограничение в документе
|
||||
- **Теги:** goal:state-integrity
|
||||
|
||||
Ревью Fable 2026-07-08 (приём). Две связанные находки о доверии к парам xt в magnet (предпосылки к F1).
|
||||
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
# 🎯 Раздача приносится и подтверждается из любого транспорта
|
||||
|
||||
- **Тип:** goal
|
||||
- **Секция:** Направления
|
||||
- **Зачем:** путь «принести раздачу и подтвердить догадку» упирается в незакрытые куски интерфейсов, а не в логику
|
||||
- **Теги:** decomposed
|
||||
|
||||
Ради чего: приём и ревью — единственные места, где система встречается с человеком. Здесь копятся незакрытые куски: фетч по URL, редактор маппинга, привязка уведомлений к автору, латентность обновлений.
|
||||
|
||||
## Завершение
|
||||
|
||||
Достигнута, когда любой из поддержанных источников принимается одним действием из любого транспорта, а ревью позволяет довести план до применимого состояния без ухода в другой инструмент.
|
||||
@@ -3,7 +3,6 @@
|
||||
- **Тип:** feature
|
||||
- **Категория:** Ядро продукта
|
||||
- **Зачем:** повторная заливка сериала целиком должна доложить недостающие эпизоды merge-раскладкой, не трогая существующие ссылки — блокирует типовой сценарий свежих сериалов
|
||||
- **Теги:** goal:complex-releases
|
||||
|
||||
Свежий сериал раздают по мере выхода: торрент с 5 из 10 эпизодов позже перезаливают целиком, пользователь добавляет раздачу повторно. Новая загрузка приходит в ту же папку за счёт правила сходимости, а раскладка становится merge — доложить только недостающее. Существующие пути не трогаем (never-overwrite, владение у старой загрузки), новые кладём (владеет новая). Split-ownership сезона принят как норма per-path модели; обе раздачи сидируют независимо.
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
- **Тип:** chore
|
||||
- **Категория:** Инфраструктура
|
||||
- **Зачем:** повторные и ретраящиеся прогоны бьют TMDB/TVDB/TVMaze одним запросом — кэш с TTL сэкономил бы лимиты и ускорил «Распознать заново»
|
||||
- **Теги:** goal:operational-resilience
|
||||
|
||||
Повторные и ретраящиеся прогоны распознавания бьют TMDB/TVDB/TVMaze одним и тем же запросом. Кэш ответов с TTL экономит лимиты API и ускоряет «Распознать заново»/«Уточнить». При желании — кэш ответов LLM по хешу входа (но он менее полезен, т.к. вход меняется подсказками).
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
- **Тип:** research
|
||||
- **Категория:** Ядро продукта
|
||||
- **Зачем:** несколько проходов распознавания с консенсусом подняли бы точность ценой стоимости/латентности — проработать, когда включать и как мерджить расхождения
|
||||
- **Теги:** goal:recognition-accuracy
|
||||
|
||||
Несколько раз извлекать данные из раздачи и контекста разными промптами, искать в метабазах, затем сводить результаты в общий вердикт (голосование/консенсус) — выше точность ценой нескольких вызовов LLM и запросов к базам. Проработать: когда включать, как мерджить расхождения, стоимость/латентность.
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
- **Тип:** feature
|
||||
- **Категория:** Ядро продукта
|
||||
- **Зачем:** стэкинг частей (part1/cd1), редакции [edition-…] и двойная серия SxxEyy-Eyy описаны нарративом, но в file-layout не заказаны — раскладка таких раздач не определена
|
||||
- **Теги:** goal:complex-releases
|
||||
|
||||
Целевые имена для типового фильма и типового сезона заказаны
|
||||
[file-layout](../../openspec/specs/file-layout/spec.md). Крайние случаи там
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
- **Тип:** feature
|
||||
- **Категория:** Ядро продукта
|
||||
- **Зачем:** пинги и ревью должен получать автор загрузки в своём транспорте — нет привязки загрузки к источнику/отправителю (нужно для мульти-бота)
|
||||
- **Теги:** goal:ingest-and-review-interfaces
|
||||
|
||||
Уведомления и запросы подтверждения должен получать тот, кто прислал загрузку: автор сообщения о новой раздаче — адресат пингов и ревью по ней. Транспортов-ботов может быть несколько (Telegram, в перспективе Matrix и др.); каждый адресует «своему» отправителю. Веб-интерфейс остаётся единым для всех и точкой правды по функциональности (боты — тонкие адаптеры над тем же ядром). Нужно: хранить у загрузки источник/транспорт и идентификатор отправителя, маршрутизировать пинги по нему.
|
||||
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
# 🎯 Сервис переживает рост и потерю тома
|
||||
|
||||
- **Тип:** goal
|
||||
- **Секция:** Сопровождение
|
||||
- **Зачем:** сервис работает, но не переживает роста: база копится вечно, бэкапа нет, отказ зависимости виден только по застрявшим задачам
|
||||
- **Теги:** decomposed
|
||||
|
||||
Ради чего: сегодня всё держится на том, что загрузок мало и всё рядом работает. Ретеншена нет, бэкапа нет, глубокого healthcheck нет, поведение под сотней загрузок не мерялось.
|
||||
|
||||
## Завершение
|
||||
|
||||
Достигнута, когда база не растёт бесконечно, состояние переживает потерю тома, отказ любой зависимости виден владельцу раньше, чем по застрявшим задачам, и поведение под сотней одновременных загрузок измерено, а не предположено.
|
||||
@@ -2,8 +2,7 @@
|
||||
|
||||
- **Тип:** chore
|
||||
- **Категория:** Инфраструктура — уступила первую строку: ready не проходит, а часть про ревьювер наименований ждёт словарь единого языка
|
||||
- **Зачем:** конвейер ревью переехал в плагин `av-dev-pipeline`; осталась калибровка проходов на этом проекте и ревьювер наименований (ждёт словарь единого языка)
|
||||
- **Теги:** goal:dev-process-quality
|
||||
- **Зачем:** конвейер ревью переехал в плагин `av-dev`; осталась калибровка проходов на этом проекте и ревьювер наименований (ждёт словарь единого языка)
|
||||
|
||||
Набор проходов ревью поверх ревью-процесса из CLAUDE.md. Развивает ревью-процесс
|
||||
OpenSpec в сторону воспроизводимых автопроверок, не заменяя человеческое ревью.
|
||||
@@ -49,7 +48,7 @@ OpenSpec в сторону воспроизводимых автопроверо
|
||||
оптикой не выделен: зависит от задачи «Словарь единого языка», без глоссария
|
||||
проверять не по чему. Завести после неё.
|
||||
- **Калибровка проходов** по процедуре `references/calibration.md` скилла
|
||||
`av-dev-pipeline:review-pipeline` — ни один проход ещё не замерен инъекцией.
|
||||
`av-dev:code-review` — ни один проход ещё не замерен инъекцией.
|
||||
До замера ничего не удаляем и промпты не правим.
|
||||
- **Проходы не сообщают свой потолок находок.** На прогоне `tvdb-title-locale`
|
||||
(2026-08-07) о потолке промолчали четверо из шести — `autotests`, `specs`,
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
# 🎯 Раздача узнаётся верно без подсказок человека
|
||||
|
||||
- **Тип:** goal
|
||||
- **Секция:** Направления
|
||||
- **Зачем:** распознавание ошибается молча и правдоподобно, а смена модели или правка промпта идёт вслепую — сдвига точности не видно ни до, ни после
|
||||
- **Теги:** decomposed
|
||||
|
||||
Ради чего: распознавание — единственное место, где система может ошибиться молча и правдоподобно. Сегодня о его точности судят по впечатлению, и сдвиг от смены модели или правки промпта заметен только задним числом.
|
||||
|
||||
Размеченный корпус и обучение на правках человека из этой цели исключены сознательно (`REJECTED.md`, 2026-08-06): базу руками не собираем, точность поднимаем тюнингом автоматического распознавания.
|
||||
|
||||
## Завершение
|
||||
|
||||
Достигнута, когда решение auto/review опирается на измеримую силу совпадения с записью метабазы, а не на самооценку модели, и доля раздач, ушедших в ревью или поправленных после авто-раскладки, видна по рабочему потоку и не растёт от версии к версии.
|
||||
@@ -3,7 +3,6 @@
|
||||
- **Тип:** feature
|
||||
- **Категория:** Ядро продукта
|
||||
- **Зачем:** правка S·E, «нумеровать подряд» и ручной режим при полном провале LLM были запланированы объёмом Ф5 и не заведены задачей — в ревью сегодня можно только подсказать текстом
|
||||
- **Теги:** goal:ingest-and-review-interfaces
|
||||
|
||||
Когда распознавание разложило файлы по сериям неверно, единственный путь —
|
||||
подсказать текстом и перераспознать. Точечно поправить номер серии у одного
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
- **Тип:** research
|
||||
- **Категория:** Инфраструктура
|
||||
- **Зачем:** Зафиксировать в НФТ ориентир 100/1000 загрузок + аудит узких мест (SQLite, воркер, поллинг)
|
||||
- **Теги:** goal:operational-resilience
|
||||
|
||||
Потолок по нагрузке нигде не зафиксирован: воркер, поллинг qBittorrent, пул LLM-вызовов и запись в SQLite спроектированы «на глаз». Записать в НФТ целевой ориентир — архитектура держит до 100 одновременных загрузок в работе (приём → распознавание → раскладка), план-максимум — 1000. Сама запись требования дешева и высокоценна: задаёт рамку для решений ниже. Отдельно (дороже) — аудит узких мест: одиночное соединение SQLite и сериализация записи, конкурентность воркера и лимит параллельных распознаваний, частота/стоимость поллинга и дедуп при наплыве.
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
- **Тип:** chore
|
||||
- **Категория:** Инфраструктура
|
||||
- **Зачем:** architecture требует бекапить data-том, но стратегия не описана — сбой или редеплой стирают всё in-flight состояние (проще, пока БД маленькая)
|
||||
- **Теги:** goal:operational-resilience
|
||||
|
||||
architecture.md требует «бекапить data-том», но как — не описано. Без понятной стратегии сбой или редеплой стирают всё in-flight состояние. Зафиксировать решение и реализовать: периодический VACUUM INTO в /data/backups по расписанию (с ротацией) либо потоковая репликация (litestream). Лучше сделать, пока БД маленькая.
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
- **Тип:** feature
|
||||
- **Категория:** Ядро продукта
|
||||
- **Зачем:** живые обновления на htmx-поллинге дают задержку и холостые запросы — SSE убрал бы то и другое (поллинг работает, поэтому улучшение, не блокер)
|
||||
- **Теги:** goal:ingest-and-review-interfaces
|
||||
|
||||
Живые обновления прогресса сейчас на htmx-поллинге (фаза 2 веб-UI) — просто и работает, но с задержкой в интервал опроса и холостыми запросами. Перевести динамический контент (прогресс загрузки, смена статуса, раздача) на Server-Sent Events, чтобы обновления приходили почти мгновенно и без лишнего поллинга. Поллинг работает, поэтому это улучшение, а не блокер; SSE — один долгоживущий ответ на соединение, ложится на server-rendered UI без тяжёлого фронтенда.
|
||||
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
# 🎯 По записи загрузки видно, как она сюда попала
|
||||
|
||||
- **Тип:** goal
|
||||
- **Секция:** Направления
|
||||
- **Зачем:** известные окна рассинхрона и потери маркеров: каждое по отдельности самоисцеляется, вместе — источник необъяснимых состояний
|
||||
- **Теги:** decomposed
|
||||
|
||||
Ради чего: состояние загрузки — то, по чему судят обо всём остальном. Накопились известные щели: окно namer'а, идентичность split v1/v2, потеря маркера dismiss, отсутствие истории переходов.
|
||||
|
||||
## Завершение
|
||||
|
||||
Достигнута, когда по записи загрузки можно ответить «как она сюда попала», ни один известный сегодня путь не оставляет состояние, которое не объясняется историей переходов, и идентичность раздачи не подделывается входом.
|
||||
@@ -3,7 +3,6 @@
|
||||
- **Тип:** research
|
||||
- **Категория:** Ядро продукта
|
||||
- **Зачем:** зонтичный проход по всем текстам бота: полнота карточек, единый язык, оформление; порождает под-задачи
|
||||
- **Теги:** goal:ingest-and-review-interfaces
|
||||
|
||||
Зонтичная задача: пройтись по всем исходящим уведомлениям и запросам подтверждения
|
||||
бота, выправить формулировки, состав данных и оформление. Тексты формируются в
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
**Два кандидата пришли из ревью `tvdb-title-locale`** (2026-08-07,
|
||||
[отчёт триажа](../../openspec/changes/archive/2026-08-07-tvdb-title-locale/review/report.md)
|
||||
→ «Promote candidates»), оба с провенансом прохода, а не из головы:
|
||||
→ «Promote candidates»), оба с названным проходом, а не из головы:
|
||||
|
||||
- **один стенд чужого API на пакет.** В `tvdb_test.go` завелись два фейка одного
|
||||
и того же API. Когда форма ответа поменяется по факту разведки, забытый
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
- **Тип:** feature
|
||||
- **Категория:** Ядро продукта
|
||||
- **Зачем:** По калибровке болей (2026-07-02) — не боль, из приоритета выпало
|
||||
- **Теги:** goal:complex-releases
|
||||
|
||||
По калибровке болей (2026-07-02) — не боль, из приоритета выпало. Сосуществование версий доступно уже сейчас (Jellyfin multi-version, другой целевой путь), коллизия на тот же путь штатно уходит в review. Явный replace (undo старого хардлинка → lay нового → супересид владения путём) — отдельный change, если/когда станет болью.
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
- **Тип:** feature
|
||||
- **Категория:** Ядро продукта
|
||||
- **Зачем:** magnet и .torrent-файл приняты; остался фетч .torrent по URL (нужен SSRF-гард)
|
||||
- **Теги:** goal:ingest-and-review-interfaces
|
||||
|
||||
Приём magnet и `.torrent`-файла уже реализован: ветка `TorrentData → torrent.Parse`
|
||||
(`internal/ingest/ingest.go`), файл-пикер в веб-форме (`web/templates/index.html`),
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
- **Тип:** research
|
||||
- **Категория:** Ядро продукта — дешевле всех и проверяет только что сделанное: при иной форме ответа TheTVDB локализация молча уходит в фолбэк, а гейт зелёный
|
||||
- **Зачем:** форма ответа поиска TheTVDB принята по swagger 4.7.10 и живым прогоном не подтверждена — при иной форме разбор молча уходит в фолбэк, гейт зелёный, локализованное название не работает
|
||||
- **Теги:** goal:recognition-accuracy
|
||||
|
||||
Задача `tvdb-title-locale` научила клиент TVDB брать локализованное название из
|
||||
блока переводов ответа `/search` и заполнять `OriginalTitle` primary name'ом. Но
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
- **Тип:** chore
|
||||
- **Категория:** Инфраструктура
|
||||
- **Зачем:** наименования домена расходятся между спеками, UI и кодом — нет единого глоссария (на нём же стоит агент-ревьювер наименований)
|
||||
- **Теги:** goal:dev-process-quality
|
||||
|
||||
Свести термины домена в один глоссарий, чтобы пользователь, документация, код и агент говорили на одном языке: загрузка, раздача, распознавание, матч, кандидат, раскладка, источник/цель, хардлинк, ревью, переход состояния и т.д. — русский термин, английский идентификатор в коде, краткое определение. Сейчас наименования расходятся между спеками, UI и кодом. Глоссарий — источник истины по именам; на нём же строится агент-ревьювер наименований.
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
- **Тип:** feature
|
||||
- **Категория:** Инфраструктура
|
||||
- **Зачем:** для v1 решено без авторизации (доверенная LAN, опц. allowlist подсетей) — задел на случай, если понадобится защита
|
||||
- **Теги:** goal:ingest-and-review-interfaces
|
||||
|
||||
Решено для v1: без авторизации в доверенной LAN, опц. allowlist подсетей (http.trusted_subnets) — как умеет qBittorrent. Если понадобится защита: токен/Basic в самом приложении или вынос за reverse-proxy с аутентификацией.
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
- **Тип:** feature
|
||||
- **Категория:** Ядро продукта
|
||||
- **Зачем:** текущий server-rendered UI функционален — PWA (устанавливаемое, удобное с телефона) это улучшение большого объёма, не блокер
|
||||
- **Теги:** goal:ingest-and-review-interfaces
|
||||
|
||||
Переделать веб-интерфейс в современное PWA-приложение (устанавливаемое, отзывчивое, удобное с телефона). Текущий server-rendered UI функционален, поэтому это улучшение, а не блокер; большой объём работы.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user