# Пропажа источника у активной загрузки (MAJOR-3) ## Why Если раздача исчезает из qBittorrent (пользователь или другой клиент удалил её), пока задача в `downloading`, задача становится **вечным зомби**. Поллинг активных загрузок промахивается по `torrentFor`, пишет `Warn "active download not found in qbittorrent"` и делает `continue` — и так каждый тик, бесконечно. Состояние не меняется, уведомления нет, телеметрии нет, `checkTimeouts` требует торрент (значит таймауты-предохранители не срабатывают). Единственный выход — ручной Cancel/Defer. Дыра: сверка рассинхрона (`state-reconciliation`) покрывает пропажу источника только для уже разложенных состояний (`done`/`target_missing`/`orphaned`), а восстановление (`reconcileRecovery`) — только `failed`/`stuck`. Для активного `downloading` пропажей источника не владеет НИКТО. Сравни: та же пропажа в `completed`/`recognizing`/`review` деградирует штатно (там источник уже не нужен или его отсутствие ведёт через матрицу). ## What Changes - Поллинг активных загрузок SHALL применять **дебаунс пропажи источника** (тот же `SourceMissCount` / `[worker].source_missing_threshold`, что и сверка рассинхрона): промах `torrentFor` наращивает счётчик, любое появление раздачи его сбрасывает. - После порога подряд идущих промахов задача SHALL переходить `downloading → failed` с новым отдельным `error_code` `source_gone` и уведомлять автора (`EventFailed`). - `source_gone` **восстановлению сверкой не подлежит** (не входит в набор `reconcileRecovery`): удаление источника из qBittorrent — намеренное действие, молча воскрешать задачу нельзя. Задача остаётся штатно **retriable**: `Retry` заново отдаёт источник (у нас сохранены magnet/`.torrent`-байты). Ребро графа `downloading → failed` уже объявлено — нового ребра не требуется. Меняется только набор `error_code` и поведение поллинга активных загрузок. ## Capabilities - `download-tracking` — ADDED: «Пропажа источника у активной загрузки». ## Impact - Код: `internal/worker/worker.go` (поллинг активных загрузок, новый `errCodeSourceGone`), тесты воркера. - Спека: `download-tracking` (новое требование). Диаграмма `docs/specs/workflow.md` (миррор FSM) — добавить ребро `downloading → failed (source_gone)`. - Миграции БД нет: `source_miss_count` уже существует, новых полей не вводим. - Конфиг без изменений: переиспользуем `source_missing_threshold`.