Итог параллельной волны фиксов (worktree-изоляция, cherry-pick в master): - ingest-dedup-integrity (F1, F6) → спека ingest - retry-stall-basis (MAJOR-1, MAJOR-2) → спека state-reconciliation - linking-transition-robustness (MAJOR-4, MINOR-7) → спеки file-layout и state-reconciliation Дельты влиты в openspec/specs, changes перенесены в openspec/changes/archive/2026-07-08-*. Беклог не трогаю (по решению). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
45 lines
2.1 KiB
Markdown
45 lines
2.1 KiB
Markdown
# Tasks: retry-stall-basis
|
|
|
|
## Схема и хранилище
|
|
|
|
- [x] Миграция `0010_retried_at.sql` — колонка `download.retried_at` (nullable TEXT).
|
|
- [x] `store.Download.RetriedAt` (`db:"retried_at"`) + метод `RetriedTime()`.
|
|
- [x] `store.SetRetriedAt(ctx, id, t)` — перезаписывающая запись базиса retry.
|
|
- [x] Обновить ER-схему `docs/specs/database.md` (строка `retried_at`).
|
|
|
|
## qBittorrent-клиент
|
|
|
|
- [x] `qbt.Torrent.LastActivity` (`json:"last_activity"`).
|
|
|
|
## Логика воркера
|
|
|
|
- [x] `checkTimeouts` — две разные меры: `magnet_timeout` по возрасту,
|
|
`stuck_after` по простою (`last_activity`).
|
|
- [x] Разбить `torrentAge` на `addedBasis` (возраст, фолбэк `created_at`),
|
|
`stallDuration` (простой от `last_activity`), `retriedFloor` (пол по
|
|
`retried_at`).
|
|
- [x] `Retry` — сброс базиса через `SetRetriedAt`; перецепка только к здоровому
|
|
живому торренту, сломанный (`classErrored`) → повторный `Add` (NIT-12).
|
|
- [x] `Store` interface воркера — метод `SetRetriedAt`.
|
|
|
|
## Спеки
|
|
|
|
- [x] Дельта `state-reconciliation` — MODIFIED «Восстановление зависшей
|
|
загрузки» (простой от `last_activity`) и «Ручной повтор» (сброс базиса,
|
|
NIT-12).
|
|
- [x] `docs/specs/workflow.md` — устранить противоречие «возраст vs простой»,
|
|
описать сброс базиса и перецепку только к здоровому торренту.
|
|
|
|
## Тесты
|
|
|
|
- [x] `TestRetryResetsTimeoutBasis` — следующий тик после retry (MAJOR-1).
|
|
- [x] `TestStallMeasuredFromLastActivity` — простой vs возраст (MAJOR-2).
|
|
- [x] `TestSetRetriedAtOverwrites` — store.
|
|
- [x] Обновить фейки (`fakeStore`, `memStore`) методом `SetRetriedAt`.
|
|
|
|
## Проверки
|
|
|
|
- [x] `openspec validate --strict retry-stall-basis`.
|
|
- [x] `task test`.
|
|
- [x] `task lint`.
|