закрыта задача catched-source-type-refresh
This commit is contained in:
@@ -10,7 +10,6 @@
|
|||||||
|
|
||||||
- [✨ Брать у TVDB название на языке настройки и оригинальное название](items/tvdb-title-locale.md) — [general].language правит только TMDB и промпт LLM — TVDB отдаёт primary name, и при language=ru в карточку ревью и имя папки попадает 哪吒之魔童降世 вместо «Нэчжа»
|
- [✨ Брать у TVDB название на языке настройки и оригинальное название](items/tvdb-title-locale.md) — [general].language правит только TMDB и промпт LLM — TVDB отдаёт primary name, и при language=ru в карточку ревью и имя папки попадает 哪吒之魔童降世 вместо «Нэчжа»
|
||||||
- [✨ Узаконить confidence-гейт авто-раскладки в спеке и сделать его выключаемым (дефолт 0.7)](items/auto-link-confidence-gate.md) — Решено (B): гейт оставляем как доп. проверку на ревью — выключаемый порог, дефолт 0.85→0.7, записать в спеку
|
- [✨ Узаконить confidence-гейт авто-раскладки в спеке и сделать его выключаемым (дефолт 0.7)](items/auto-link-confidence-gate.md) — Решено (B): гейт оставляем как доп. проверку на ревью — выключаемый порог, дефолт 0.85→0.7, записать в спеку
|
||||||
- [🧹 Уточнить в спеке требование о re-read `source_type` перед `Add`](items/catched-source-type-refresh.md) — спека требует перечитывать source_type непосредственно перед добавлением, код перечитывает после тик-снимка — узкое namer-окно самоисцеляется через Retry и признано допустимым
|
|
||||||
- [🧹 Зафиксировать в спеке разделение Cancel и Dismiss по состояниям](items/dismiss-marker-lost.md) — спека обещает dismiss из любого состояния, код осознанно даёт Cancel для активных и Dismiss для терминальных — расходится буква, а не поведение
|
- [🧹 Зафиксировать в спеке разделение Cancel и Dismiss по состояниям](items/dismiss-marker-lost.md) — спека обещает dismiss из любого состояния, код осознанно даёт Cancel для активных и Dismiss для терминальных — расходится буква, а не поведение
|
||||||
- [🐞 Тормозить опрос qBittorrent бэкоффом при недоступности и эскалировать устойчивый сбой](items/background-error-noise.md) — недоступный qBittorrent опрашивается каждые 5 с и даёт WARN на каждом тике: нужен экспоненциальный бэкофф до минутного потолка со сбросом по первому успеху и ERROR на устойчивой деградации
|
- [🐞 Тормозить опрос qBittorrent бэкоффом при недоступности и эскалировать устойчивый сбой](items/background-error-noise.md) — недоступный qBittorrent опрашивается каждые 5 с и даёт WARN на каждом тике: нужен экспоненциальный бэкофф до минутного потолка со сбросом по первому успеху и ERROR на устойчивой деградации
|
||||||
- [🧹 Закрыть мелочи приёма: NoName в контексте, устаревшие комментарии, лог без причины, bencode-аллокации (N1, N3, N4, N5)](items/ingest-nits.md) — косметика приёма: NoName в контексте, устаревшие комментарии, лог, bencode-аллокации _(ревью 2026-07-08)_
|
- [🧹 Закрыть мелочи приёма: NoName в контексте, устаревшие комментарии, лог без причины, bencode-аллокации (N1, N3, N4, N5)](items/ingest-nits.md) — косметика приёма: NoName в контексте, устаревшие комментарии, лог, bencode-аллокации _(ревью 2026-07-08)_
|
||||||
|
|||||||
@@ -1,80 +0,0 @@
|
|||||||
# 🧹 Уточнить в спеке требование о re-read `source_type` перед `Add`
|
|
||||||
|
|
||||||
- **Тип:** chore
|
|
||||||
- **Категория:** Ядро продукта
|
|
||||||
- **Зачем:** спека требует перечитывать source_type непосредственно перед добавлением, код перечитывает после тик-снимка — узкое namer-окно самоисцеляется через Retry и признано допустимым
|
|
||||||
|
|
||||||
Найдено аудитом capability **download-tracking** (сверка код↔спека после пачки
|
|
||||||
lifecycle-задач). Пред-существующее, вне scope задачи F3/cancel-cleanup — T4
|
|
||||||
осознанно вынес это за рамки и задокументировал в своём design.md.
|
|
||||||
|
|
||||||
## Суть
|
|
||||||
|
|
||||||
`processCatched` (`internal/worker/worker.go:442-517`) строит `addReq` из записи
|
|
||||||
`cur`, перечитанной под замком на `:447-455`, **до** вызова namer'а (LLM, секунды,
|
|
||||||
вне замка, `:463-478`). Затем на `:484-491` под замком перечитывается `before`,
|
|
||||||
но `addReq` из него **не пересобирается** — проверяется только `state == catched`.
|
|
||||||
|
|
||||||
Если апгрейд пойманной magnet-задачи до `.torrent`
|
|
||||||
(`UpgradeCatchedMagnetToTorrent`, `internal/store/download.go:392`) отработает
|
|
||||||
именно в окне namer'а (приём принял `.torrent` с тем же infohash, `state`
|
|
||||||
остаётся `catched`), воркер добавит **magnet-ссылку из устаревшего снимка**, хотя
|
|
||||||
в БД уже `source_type=torrent`.
|
|
||||||
|
|
||||||
Спека (`openspec/specs/download-tracking/spec.md`, раздел про добавление по
|
|
||||||
`source_type`) требует перечитывать `source_type` **под блокировкой переходов
|
|
||||||
непосредственно перед добавлением** — сейчас это требование в окне namer'а
|
|
||||||
нарушается.
|
|
||||||
|
|
||||||
## Насколько больно
|
|
||||||
|
|
||||||
Ограниченно и самоисцеляемо: на закрытом трекере magnet без метаданных зависнет
|
|
||||||
в `metaDL` → предохранитель `magnet_timeout` → `failed`; ручной `Retry`
|
|
||||||
перечитает актуальный `source_type` и добьёт. Данные не страдают, инвариант
|
|
||||||
«источник неприкосновенен» не задет. Окно узкое (апгрейд должен лечь ровно в
|
|
||||||
LLM-вызов по тому же infohash). Поэтому средний, не высокий.
|
|
||||||
|
|
||||||
## Решение (2026-08-06): B — привести спеку к коду
|
|
||||||
|
|
||||||
Рациональ требования — «не полагаться на снимок, снятый ранее вне блокировки» —
|
|
||||||
уже выполнен первым re-read под замком на `:447`. Требование переформулируется
|
|
||||||
как «перечитывать `source_type` под блокировкой после тик-снимка», а узкое
|
|
||||||
namer-окно принимается явно: оно самоисцеляется через `magnet_timeout` →
|
|
||||||
`failed` → `Retry`.
|
|
||||||
|
|
||||||
Вариант A (пересобирать `addReq` из `before` под замком) отклонён: не
|
|
||||||
однострочник — `sourceAddParts` читает байты `.torrent`, держать это под
|
|
||||||
блокировкой нельзя, а при апгрейде корректно был бы и повторный вызов namer'а.
|
|
||||||
Заводить его отдельной задачей, только если узкое окно окажется реальной болью в
|
|
||||||
эксплуатации.
|
|
||||||
|
|
||||||
Кода задача не трогает: наблюдаемое поведение остаётся прежним, меняется
|
|
||||||
заявленное.
|
|
||||||
|
|
||||||
## Затрагивает
|
|
||||||
|
|
||||||
- `openspec/specs/download-tracking/spec.md` — требование про re-read
|
|
||||||
`source_type` перед добавлением, его формулировка и сценарии;
|
|
||||||
- дельта-спека change'а — новых сценариев с namer-окном может потребоваться два
|
|
||||||
(апгрейд до тик-снимка и апгрейд в окне namer'а);
|
|
||||||
- `internal/worker/worker.go` — только чтение, правок не предполагается.
|
|
||||||
|
|
||||||
## Критерии приёмки
|
|
||||||
|
|
||||||
- Требование спеки описывает фактическое поведение: re-read `source_type` под
|
|
||||||
блокировкой после тик-снимка, апгрейд в окне namer'а назван допустимым и
|
|
||||||
самоисцеляемым (оракул: `openspec validate --strict`).
|
|
||||||
- В спеке есть сценарий, покрывающий апгрейд в окне namer'а с исходом «magnet из
|
|
||||||
снимка, дальше `magnet_timeout` → `failed` → `Retry`» (оракул: тот же прогон
|
|
||||||
плюс существующий `TestProcessCatchedReReadsSourceTypeUnderLock` продолжает
|
|
||||||
проходить без правок).
|
|
||||||
- Ни один файл под `internal/` в диффе не изменён (оракул: `git diff --stat`
|
|
||||||
в отчёте ревью).
|
|
||||||
|
|
||||||
## Ссылки
|
|
||||||
|
|
||||||
- `internal/worker/worker.go:442-517` — `processCatched`
|
|
||||||
- `internal/store/download.go:392` — `UpgradeCatchedMagnetToTorrent`
|
|
||||||
- `openspec/specs/download-tracking/spec.md` — требование про `source_type`
|
|
||||||
- Тест `TestProcessCatchedReReadsSourceTypeUnderLock` покрывает апгрейд между
|
|
||||||
тик-снимком и re-read, но **не** окно namer'а.
|
|
||||||
Reference in New Issue
Block a user