download-tracking: требование о re-read source_type приведено к коду

- re-read `source_type` перечитывается под блокировкой после тик-снимка, а
  остаточное окно вывода имени названо известным ограничением с ценой и
  достоверным маршрутом восстановления (ручной шаг + `Retry`, не самоисцеление)
- в `ingest` снята парная ложная гарантия «воркер добавит раздачу файлом»,
  добавлены сценарии на оба окна апгрейда и на недоступные байты `.torrent`
- заведён ADR о том, что при разрыве спека↔код двигается тот, чья формулировка
  сильнее рационали
This commit is contained in:
av
2026-08-06 14:44:21 +03:00
parent f42db0a275
commit 30ee598547
11 changed files with 1179 additions and 11 deletions
+22 -6
View File
@@ -511,11 +511,15 @@ v2-хеш (для v2/гибридного файла, BEP52) SHALL извлек
привязав их к этой загрузке, и сменить её `source_type` на `torrent`. Тем
самым воркер добавит раздачу файлом, а не magnet-хешем (иначе на закрытом
трекере без DHT метаданные не докачаются, а magnet застрянет в metaDL →
failed). Апгрейд SHALL применяться ТОЛЬКО пока загрузка в `catched` (воркер
источник ещё не добавил); для уже добавленной (`downloading` и далее)
загрузки смена `source_type` при дедупе выполняться SHALL NOT — её судьба
решается путями retry/сверки, а не приёмом. Апгрейд SHALL быть best-effort:
его неуспех приём не прерывает.
failed) — **при условии, что апгрейд лёг до того, как воркер подготовил запрос
на добавление**. Апгрейд, попавший в узкое окно вывода отображаемого имени,
воркер уже не подхватит и добавит magnet: это известное ограничение, названное в
`download-tracking` «Добавление пойманной загрузки в qBittorrent» вместе с
маршрутом восстановления. Апгрейд SHALL применяться ТОЛЬКО пока загрузка в
`catched` (воркер источник ещё не добавил); для уже добавленной (`downloading`
и далее) загрузки смена `source_type` при дедупе выполняться SHALL NOT — её
судьба решается путями retry/сверки, а не приёмом. Апгрейд SHALL быть
best-effort: его неуспех приём не прерывает.
Из полей `.torrent` система SHALL синтезировать контекст распознавания (имя
раздачи, суммарный размер, сигнал по дереву файлов, домен трекера, комментарий)
@@ -567,7 +571,19 @@ NOT.
- **THEN** новая загрузка не создаётся, возвращается существующая
- **AND** байты `.torrent` сохраняются привязанными к ней, а её `source_type`
становится `torrent` — в одной транзакции
- **AND** воркер добавит раздачу файлом (не по magnet)
- **AND** воркер добавит раздачу файлом (не по magnet), если апгрейд лёг до
подготовки запроса на добавление — см. `download-tracking` «Добавление
пойманной загрузки в qBittorrent»
#### Scenario: Апгрейд в окне вывода имени — воркер добавит magnet
- **GIVEN** активная загрузка в `catched` с `source_type = magnet`, для которой
воркер уже подготовил запрос на добавление и выводит отображаемое имя
- **WHEN** принимается `.torrent` с тем же инфохэшем
- **THEN** апгрейд применяется (байты сохранены, `source_type` стал `torrent`)
- **AND** гарантии, что воркер добавит раздачу файлом, приём в этом случае не
даёт: исход добавления определяет `download-tracking` «Добавление пойманной
загрузки в qBittorrent», где это окно и его цена описаны
#### Scenario: Magnet-задача уже добавлена — апгрейда нет