From 5a8c43989973e71c45893c3496e93a1d627d9fa3 Mon Sep 17 00:00:00 2001 From: Anton Vakhrushev Date: Thu, 6 Aug 2026 14:45:01 +0300 Subject: [PATCH] =?UTF-8?q?=D0=B7=D0=B0=D0=BA=D1=80=D1=8B=D1=82=D0=B0=20?= =?UTF-8?q?=D0=B7=D0=B0=D0=B4=D0=B0=D1=87=D0=B0=20catched-source-type-refr?= =?UTF-8?q?esh?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/tasks/SPRINT.md | 1 - .../items/catched-source-type-refresh.md | 80 ------------------- 2 files changed, 81 deletions(-) delete mode 100644 docs/tasks/items/catched-source-type-refresh.md diff --git a/docs/tasks/SPRINT.md b/docs/tasks/SPRINT.md index 95ffea5..b827faf 100644 --- a/docs/tasks/SPRINT.md +++ b/docs/tasks/SPRINT.md @@ -10,7 +10,6 @@ - [✨ Брать у 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, записать в спеку -- [🧹 Уточнить в спеке требование о 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 для терминальных — расходится буква, а не поведение - [🐞 Тормозить опрос 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)_ diff --git a/docs/tasks/items/catched-source-type-refresh.md b/docs/tasks/items/catched-source-type-refresh.md deleted file mode 100644 index 500db1a..0000000 --- a/docs/tasks/items/catched-source-type-refresh.md +++ /dev/null @@ -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'а.