Files
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

57 lines
4.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
## Why
Команды ревью, которым нужен источник, проверяют лишь **наличие** раздачи в
qBittorrent (`ensureSourcePresent`), но не её **готовность** (файлы докачаны).
Недокачанную задачу можно легально припарковать в `deferred` (граф допускает
`*→deferred`), а затем «Распознать заново»: она уходит в `recognizing`, LLM
видит имена ещё не докачанных файлов (qBittorrent отдаёт их до завершения) и при
уверенном матче срабатывает авто-раскладка (Rerecognize/Refine/SetType не ставят
`force_review`) — хардлинки создаются на **неполные файлы**, задача уходит в
`done`, Jellyfin сканирует половину. Даже ручной `review → Применить` не имеет
preflight завершённости. Это обходит смысл состояния `completed`
(«готовность только когда файлы на месте») и портит целостность медиатеки —
самый опасный из выявленных дефектов жизненного цикла.
## What Changes
- Ввести синхронный preflight **готовности** источника `ensureSourceReady`:
источник должен не только присутствовать, но и быть в готовом к раскладке
классе (`classify(t.State) == classReady`).
- Заменить `ensureSourcePresent` на `ensureSourceReady` во **всех** командах
ревью, которым нужен источник: `Rerecognize`, `Refine`, `SetType`, `Relink`.
Единый инвариант — команда, вводящая задачу в активную обработку
(`recognizing`) или в раскладку, работает только с готовым источником.
- Добавить ту же проверку готовности в `Apply` (сейчас он берёт торрент
inline и не смотрит на его класс) — последний рубеж перед созданием
хардлинков.
- Недокачанный источник → отказ отдельным sentinel `ErrNotReady` (409) с
actionable-сообщением «торрент ещё качается», **без** `reconcileToReality`:
состояние `deferred`/`review`/… легитимно, приводить к реальности нечего —
просто не даём действовать. Транспорты (HTTP/htmx и Telegram) показывают
конкретный текст, а не генерик «действие недоступно».
## Capabilities
### New Capabilities
<!-- нет новых capability -->
### Modified Capabilities
- `review`: команды ревью, которым нужен источник, SHALL проверять его
**готовность** (файлы докачаны), а не только наличие; недокачанный источник
→ отказ без разрушающих действий.
## Impact
- Код: `internal/worker/errors.go` (новый sentinel `ErrNotReady`),
`internal/worker/reconcile.go` (новый `ensureSourceReady`, удаление
`ensureSourcePresent`), `internal/worker/review.go` (замена вызовов в
`Rerecognize`/`Refine`/`SetType`/`Relink`, добавление проверки в `Apply`).
- Транспорты: `internal/httpapi` (`classifyErr` — кейс `ErrNotReady` → 409 с
текстом «торрент ещё качается»), `internal/tgbot` (ветка `ErrNotReady` в
обработчике действий). Пользователь видит конкретную причину вместо тихой
авто-раскладки неполных файлов; трансляция — на внешней границе.
- Тесты: `internal/worker/review_test.go` — сценарии недокачанного источника
для затронутых команд.
- Данные: устраняет создание хардлинков на неполные файлы (целостность
медиатеки Jellyfin).