## Context Фикс простой (гард одной команды + снятие мёртвого ребра графа). Дизайн фиксирует два решения, чтобы ревью дизайна прошло до кода. ## Решение 1: где гардить Defer `Defer` (`review.go`) отличается от прочих команд ревью: он не использует `requireReviewable` (review/deferred), а сознательно широк — паркует любую не-терминальную задачу (downloading/completed/recognizing/review/linking/stuck/ deferred), потому что «отложить» осмысленно и для ещё качающейся задачи. Значит фикс НЕ «сузить Defer до reviewable», а точечно исключить пре-источниковое `catched`. Гард добавляем в сам `Defer` после `GetDownload`, рядом с существующей проверкой `IsTerminal()`: `if d.State == store.StateCatched { return ...ErrConflict }`. `ErrConflict` уже маппится в `httpapi.classifyErr` → 409 «действие недоступно в текущем состоянии» (см. docs/conventions/errors.md), новый sentinel не нужен. Сообщение обёртки — операторская диагностика для логов; наружу транспорт отдаёт нейтральный маппинг. ## Решение 2: граф переходов `allowedTransitions[StateCatched]` содержит `StateDeferred`. После гарда это ребро мёртвое (единственный переход в `deferred` — команда `Defer`). Убираем `StateDeferred` из исходящих `catched`, чтобы граф оставался тесным надмножеством реальных переходов (инвариант спеки «граф — источник истины о легальности рёбер»). Обновляем комментарий инварианта `deferred` в download.go («из КАЖДОГО не-терминального» → «кроме пре-источникового catched») и тест `transition_test.go`, который его закрепляет. Проверка полноты пре-источниковых состояний: `catched` — единственное не-терминальное состояние без раздачи в qBittorrent. От `downloading` и далее раздача есть; приёмное падение до `downloading` — терминальный `failed` (`qbit_add`), Defer его уже отклоняет через `IsTerminal()`. Значит достаточно исключить `catched`. ## Границы scope Не трогаем `processCatched`, `reconcile`, граф `deleted`: корень бага — единственный вход в лимбо (`catched → deferred`), закрытие входа устраняет всю цепочку. Альтернативы из файла задачи (резюме deferred в processCatched; preflight «источника не было» → failed/qbit_add) не нужны — вердикт задачи «простой фикс».