# Пропажа источника у активной загрузки (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`.
