Ревью: 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>
This commit is contained in:
av
2026-07-08 16:40:49 +03:00
co-authored by Claude Opus 4.8
parent a43adea723
commit b1bca98738
16 changed files with 475 additions and 41 deletions
+7
View File
@@ -6,3 +6,10 @@ import "errors"
// вне review/deferred, undo вне done). Это нормальный конфликт состояния, а не
// сбой сервера: транспорт матчит его через errors.Is и отвечает 409, не 500.
var ErrConflict = errors.New("conflict")
// ErrNotReady — источник (раздача) присутствует в qBittorrent, но ещё не
// докачан (не в классе classReady), поэтому команда, ведущая к распознаванию
// или раскладке, отклонена: хардлинки на неполные файлы недопустимы. Отдельно
// от ErrConflict (тоже 409), потому что причина actionable — «дождись докачки»
// — и транспорт показывает её конкретным текстом, а не генериком конфликта.
var ErrNotReady = errors.New("source not ready")