Files
jellybit/openspec/changes/archive/2026-07-08-review-readiness-preflight/tasks.md
T
avandClaude Opus 4.8 b1bca98738 Ревью: preflight готовности источника для команд ревью (MAJOR-5)
Команды ревью проверяли только наличие раздачи в qBittorrent, но не её
готовность. Недокачанную задачу можно припарковать в deferred, затем
«Распознать заново» → recognizing → авто-раскладка (Rerecognize/Refine/
SetType не ставят force_review) → хардлинки на неполные файлы. Даже ручной
Apply не имел preflight завершённости.

Вводим ensureSourceReady (classify(t.State)==classReady) вместо
ensureSourcePresent во всех командах, которым нужен источник (Relink/
Rerecognize/Refine/SetType), и inline-проверку класса в Apply — последний
рубеж перед хардлинками. Недокачанный источник → отдельный sentinel
ErrNotReady (409) с actionable-текстом «торрент ещё качается» в web и
Telegram, без reconcile (состояние deferred/review легитимно).

Change review-readiness-preflight заархивирован, дельта влита в
openspec/specs/review.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 16:40:49 +03:00

3.0 KiB
Raw Blame History

1. Preflight готовности источника

  • 1.1 В internal/worker/errors.go добавить sentinel var ErrNotReady = errors.New(...) (отдельный от ErrConflict).
  • 1.2 В internal/worker/reconcile.go добавить ensureSourceReady(ctx, d, op): найти торрент через torrentByInfohash; нет источника → reconcileToReality(false) + ErrConflict «источник удалён из qBittorrent»; есть, но classify(t.State) != classReadyErrNotReady «op: торрент ещё качается» без reconcileToReality.
  • 1.3 Заменить ensureSourcePresent на ensureSourceReady в командах Rerecognize, Refine, SetType, Relink (internal/worker/review.go); удалить осиротевший ensureSourcePresent.
  • 1.4 В Apply добавить проверку класса на уже полученном торренте (classify(t.State) != classReady → ErrNotReady «торрент ещё качается»), без второго запроса к qBittorrent.

2. Трансляция ошибки в транспортах

  • 2.1 internal/httpapi classifyErr: кейс errors.Is(err, worker.ErrNotReady) → 409, «торрент ещё качается, дождитесь докачки» (отдельно от генерик-ErrConflict).
  • 2.2 internal/tgbot: в обработчике callback-действий ветка errors.Is(err, worker.ErrNotReady) → сообщение «Торрент ещё качается…», иначе прежний opErr(...).

3. Тесты

  • 3.1 Тест: недокачанный источник (downloading-класс) отклоняет Rerecognize/Refine/SetType/Relink с ErrNotReady, состояние задачи не меняется, авто-раскладка не запускается.
  • 3.2 Тест: недокачанный источник отклоняет Apply — хардлинки не создаются, состояние не меняется.
  • 3.3 Тест: готовый источник (classReady) пропускает те же команды как раньше (регресс не сломан); отсутствие источника по-прежнему приводит к реальности и отказывает.
  • 3.4 Тест транспорта: classifyErr(ErrNotReady) == 409 с конкретным текстом (internal/httpapi).

4. Ревью и сверка

  • 4.1 task test и task lint зелёные.
  • 4.2 Ревью кода (второй чекпоинт) перед archive.
  • 4.3 openspec validate review-readiness-preflight --strict зелёный; удалить docs/backlog/review-major5-readiness-preflight.md из беклога и строку из индекса (суть переехала в спеку).