## 1. Код

- [x] 1.1 `internal/worker/review.go` — в `Defer` после `GetDownload` добавить
  гард: `d.State == store.StateCatched` → `ErrConflict` с понятным сообщением
  (отложить можно только после добавления торрента в qBittorrent), не меняя
  состояние. Существующий гард `IsTerminal()` оставить.
- [x] 1.2 `internal/store/download.go` — убрать `StateDeferred` из исходящих
  `StateCatched` в `allowedTransitions`; уточнить комментарий инварианта
  `deferred` («из КАЖДОГО не-терминального» → «кроме пре-источникового
  `catched`»).

## 2. Тесты

- [x] 2.1 `internal/worker/review_test.go` — `Defer` из `catched` возвращает
  `ErrConflict`, состояние остаётся `catched`; контроль — `Defer` из `review`
  по-прежнему уводит в `deferred` (существующий `TestDefer`).
- [x] 2.2 `internal/store/transition_test.go` — обновить инвариант `deferred`:
  легальная цель из каждого не-терминального состояния, КРОМЕ `catched` (и
  самопереход `deferred`); добавить проверку, что `catched → deferred` не
  легально.

## 3. Спека

- [x] 3.1 MODIFIED-требование «Команды ревью и их эффекты» в `review`;
  `openspec validate --strict` зелёный.

## 4. Проверка

- [x] 4.1 `task test` и `task lint` зелёные; существующие тесты
  worker/httpapi/store не сломаны.
