From 06a0e1ce41dfb929643f1a9adb38cdf781dbec19 Mon Sep 17 00:00:00 2001 From: Anton Vakhrushev Date: Fri, 17 Jul 2026 20:36:04 +0300 Subject: [PATCH] =?UTF-8?q?OpenSpec:=20=D0=B0=D1=80=D1=85=D0=B8=D0=B2=20ch?= =?UTF-8?q?ange=20retry-reject-broken-torrent=20(=D1=81=D0=B8=D0=BD=D0=BA?= =?UTF-8?q?=20state-reconciliation)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 (1M context) --- .../proposal.md | 0 .../specs/state-reconciliation/spec.md | 0 .../tasks.md | 0 openspec/specs/state-reconciliation/spec.md | 32 +++++++++++-------- 4 files changed, 18 insertions(+), 14 deletions(-) rename openspec/changes/{2026-07-17-retry-reject-broken-torrent => archive/2026-07-17-2026-07-17-retry-reject-broken-torrent}/proposal.md (100%) rename openspec/changes/{2026-07-17-retry-reject-broken-torrent => archive/2026-07-17-2026-07-17-retry-reject-broken-torrent}/specs/state-reconciliation/spec.md (100%) rename openspec/changes/{2026-07-17-retry-reject-broken-torrent => archive/2026-07-17-2026-07-17-retry-reject-broken-torrent}/tasks.md (100%) diff --git a/openspec/changes/2026-07-17-retry-reject-broken-torrent/proposal.md b/openspec/changes/archive/2026-07-17-2026-07-17-retry-reject-broken-torrent/proposal.md similarity index 100% rename from openspec/changes/2026-07-17-retry-reject-broken-torrent/proposal.md rename to openspec/changes/archive/2026-07-17-2026-07-17-retry-reject-broken-torrent/proposal.md diff --git a/openspec/changes/2026-07-17-retry-reject-broken-torrent/specs/state-reconciliation/spec.md b/openspec/changes/archive/2026-07-17-2026-07-17-retry-reject-broken-torrent/specs/state-reconciliation/spec.md similarity index 100% rename from openspec/changes/2026-07-17-retry-reject-broken-torrent/specs/state-reconciliation/spec.md rename to openspec/changes/archive/2026-07-17-2026-07-17-retry-reject-broken-torrent/specs/state-reconciliation/spec.md diff --git a/openspec/changes/2026-07-17-retry-reject-broken-torrent/tasks.md b/openspec/changes/archive/2026-07-17-2026-07-17-retry-reject-broken-torrent/tasks.md similarity index 100% rename from openspec/changes/2026-07-17-retry-reject-broken-torrent/tasks.md rename to openspec/changes/archive/2026-07-17-2026-07-17-retry-reject-broken-torrent/tasks.md diff --git a/openspec/specs/state-reconciliation/spec.md b/openspec/specs/state-reconciliation/spec.md index ce8df2e..ff65f31 100644 --- a/openspec/specs/state-reconciliation/spec.md +++ b/openspec/specs/state-reconciliation/spec.md @@ -153,17 +153,20 @@ Retry SHALL переводить задачу обратно в `downloading`, Если источник задачи уже жив и ЗДОРОВ в qBittorrent, retry SHALL перецепляться к существующему торренту, а не добавлять источник повторно вслепую. Если же живой торрент в состоянии ошибки qBittorrent (`error`/`missingFiles`), retry -перецепляться к нему SHALL NOT (перецепка к сломанному торренту тут же вернула -бы задачу в `failed` по сверке) и SHALL повторно отдать источник, как при -отсутствии раздачи. Повторный `Add` выполняется, только когда раздачи в -qBittorrent нет ЛИБО она сломана. +SHALL отклоняться с понятным пользователю сообщением — починить раздачу +(`recheck`/восстановить файлы) в qBittorrent и повторить. Повторная отдача +источника такой торрент не чинит (qBittorrent отверг бы дубль), а простой +возврат в `downloading` тут же снова упал бы `qbit_error` по сверке (+ дебаунс +уведомления) — retry выглядел бы сломанным. При отказе состояние задачи +(`failed`/`stuck`) система менять SHALL NOT и повторный `Add` выполнять SHALL NOT. -Повторный `Add` при retry система SHALL выполнять **по типу источника** -(`source_type`), как и добавление пойманной загрузки (см. `download-tracking` -«Добавление пойманной загрузки в qBittorrent»): magnet/url — ссылкой; torrent — -сохранёнными байтами `.torrent` файлом. Для torrent-источника retry БЕЗ живой -раздачи система SHALL добавлять раздачу байтами и SHALL NOT активировать задачу -в `downloading`, не добавив её (иначе задача повиснет как «нет в qBittorrent»). +Повторный `Add` при retry система SHALL выполнять, только когда раздачи в +qBittorrent нет, — **по типу источника** (`source_type`), как и добавление +пойманной загрузки (см. `download-tracking` «Добавление пойманной загрузки в +qBittorrent»): magnet/url — ссылкой; torrent — сохранёнными байтами `.torrent` +файлом. Для torrent-источника retry БЕЗ живой раздачи система SHALL добавлять +раздачу байтами и SHALL NOT активировать задачу в `downloading`, не добавив её +(иначе задача повиснет как «нет в qBittorrent»). #### Scenario: Retry упавшей magnet-загрузки из веб-UI @@ -195,14 +198,15 @@ qBittorrent нет ЛИБО она сломана. torrent сохранёнными байтами файлом - **AND** задача переходит в `downloading` -#### Scenario: Retry сломанного живого торрента повторно отдаёт источник +#### Scenario: Retry сломанного живого торрента отклоняется - **GIVEN** задача в `failed`, её торрент присутствует в qBittorrent, но в состоянии ошибки (`error`/`missingFiles`) - **WHEN** пользователь инициирует retry -- **THEN** источник отдаётся заново (перецепка к сломанному торренту не - выполняется) -- **AND** задача переходит в `downloading` +- **THEN** retry отклоняется с сообщением починить раздачу (`recheck`) в + qBittorrent +- **AND** состояние задачи не меняется (остаётся `failed`), повторный `Add` не + выполняется #### Scenario: Retry torrent-загрузки без живого источника