# Tasks — Пропажа источника у активной загрузки

## 1. Код воркера

- [x] 1.1 Ввести `errCodeSourceGone = "source_gone"` в блок кодов ошибок
  (`internal/worker/worker.go`) с комментарием: distinct-код, восстановлению
  сверкой не подлежит, retriable вручную.
- [x] 1.2 Перестроить активный цикл в `Poll`: при промахе `torrentFor` прогонять
  `debounceSource`; при исчерпании порога — `transition downloading → failed`
  (`source_gone`); до порога — `continue`; при наличии источника — сброс счётчика
  и обычная сверка (`captureInfohashes`/`captureSourceAddedAt`/`reconcile`).
- [x] 1.3 Убедиться, что `debounceSource` вызывается и при наличии источника
  (сброс накопленных промахов).
- [x] 1.4 `Retry` сбрасывает `source_miss_count` в 0 (рядом с `SetRetriedAt`),
  чтобы retried `source_gone`-задача получила полное грейс-окно, а не падала
  сразу (см. design «Сброс source_miss_count при Retry»).

## 2. Тесты

- [x] 2.1 Промах < порога → задача остаётся `downloading`.
- [x] 2.2 Промах ≥ порога → `downloading → failed`/`source_gone` + `EventFailed`.
- [x] 2.3 Возврат раздачи до порога → счётчик сброшен, задача ведётся обычной
  сверкой.
- [x] 2.4 `source_gone` не воскрешается `reconcileRecovery` (источник вернулся —
  задача остаётся `failed`).
- [x] 2.5 `Retry` задачи `source_gone` сбрасывает `source_miss_count`: после
  retry с ещё-не-видимой раздачей задача остаётся `downloading` полный порог
  тиков (грейс-окно не съедено).

## 3. Документация

- [x] 3.1 `docs/specs/workflow.md`: добавить ребро `downloading → failed`
  (`source_gone`, пропажа источника) в диаграмму и список переходов.

## 4. Верификация

- [x] 4.1 `task test` / `task lint` зелёные.
- [x] 4.2 `openspec validate downloading-source-gone --strict`.
