Беклог: переоформить path-2 удаления в одну задачу «полное удаление»

Обсудили: для сервиса одного окна основное действие — удалить всё разом (раздачу
+ файлы в библиотеке), чтобы освободить место. Из-за хардлинков иначе место и не
вернуть — снять надо обе ссылки на инод. Задача udalenie-edinoe-okno переписана в
одну конкретную:

- действие «Удалить» на загрузке: снять живые хардлинки (undo-механика, superseded
  пропускаем) + удалить раздачу с файлами из qBittorrent (новый метод qbt);
  осознанно обходим предохранитель последней копии; обязательное подтверждение;
- undo (перераспознать, гард включён) vs delete (освободить место, гард выключен)
  зафиксированы как разные действия;
- терминальное состояние — переиспользуем deleted, инициатора (user/reconcile)
  пишем в лог перехода; в граф добавить ребро done→deleted;
- тайтл-группа и экран состава выкинуты как оверинжиниринг; мультивыбор в списке —
  опциональный шаг.

Реализовать как OpenSpec-change. Приоритет высокий (недостающая половина одного
окна, частый сценарий «досмотрел → освободить место»).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
av
2026-07-08 15:43:26 +03:00
co-authored by Claude Opus 4.8
parent 2ed42b3e18
commit a43adea723
2 changed files with 48 additions and 9 deletions
+1 -1
View File
@@ -18,7 +18,7 @@ Tududi (проект `jellybit`) больше **не** держит беклог
- [Проблема второго сезона (сходимость папки сериала)](vtoroy-sezon-shodimost-papki.md) — Второй/третий сезон должен ложиться в ТУ ЖЕ папку сериала, а не заводить рядом почти…
- [Раздачи с докачиванием (merge при повторном добавлении)](merge-dokachivanie.md) — Свежий сериал раздают по мере выхода: торрент с 5 из 10 эпизодов позже перезаливают…
- [Удаление средствами jellybit («единое окно», path 2)](udalenie-edinoe-okno.md) — Распознавание ручного удаления и пометка рассинхрона уже сделаны (state-reconciliation…
- [Полное удаление загрузки из jellybit («единое окно», path 2)](udalenie-edinoe-okno.md) — Действие «Удалить»: снять хардлинки + снести раздачу+файлы из qBittorrent → освободить место (отдельно от undo)
- [Ретеншн и очистка БД](retention-ochistka-bd.md) — Терминальные задачи (done/cancelled/failed/reverted), их попытки recognition с сырыми…
- [Eval-харнес распознавания (корпус кейсов + метрика точности)](eval-harness-raspoznavaniya.md) — Распознавание — ядро продукта, но смена модели или правка промпта сейчас вслепую…
- [Гейт дозаписи хешей в dedup-ветке CreateDownloadIfNoActive (F1)](review-f1-gate-dozapisi-heshey.md) — dedup-ветка дописывает все хеши в найденную задачу без гарда — риск инварианта ≤1 активной _(ревью 2026-07-08)_
+47 -8
View File
@@ -1,13 +1,52 @@
# Удаление средствами jellybit («единое окно», path 2)
# Полное удаление загрузки из jellybit («единое окно», path 2)
**Приоритет:** высокий
Распознавание ручного удаления и пометка рассинхрона уже сделаны (state-reconciliation: target_missing/orphaned/deleted, безопасный undo с nlink-гардом, preflight). Осталось (path 2) — удалять просмотренное из самого jellybit, не идя руками в qBittorrent/Jellyfin. «Тайтл» — вычисляемая группа загрузок по (provider, provider_id)/общей папке, без новой сущности; удаление целиком — обход загрузок группы штатным undo; удаление раздачи из qBittorrent — осознанный выход за инвариант «источник неприкосновенен», только по явному подтверждению.
Безопасная половина «единого окна» уже в проде: распознавание ручного удаления и
пометка рассинхрона (state-reconciliation — `target_missing`/`orphaned`/`deleted`,
undo с nlink-гардом, preflight). Осталась вторая половина — **удалять из самого
jellybit**, не идя руками в qBittorrent/Jellyfin.
Шаги:
- удаление одной загрузки: снять живые хардлинки (штатный undo, superseded пропускаем, nlink-гард) + опц. удалить раздачу из qBittorrent с файлами — с подтверждением
- вычисляемая группа «тайтл» в UI: состав сериала/фильма одним экраном
- удаление тайтла целиком: обход загрузок группы + опц. снос опустевшей папки
- после полного удаления память о тайтле не остаётся
Основной сценарий одного окна — «досмотрел → освободить место»: удалить и раздачу,
и файлы в библиотеке разом. Из-за хардлинков иначе место и не вернуть — файл в
`downloads/` (qBittorrent) и наша ссылка в библиотеке указывают на **один инод**,
диск освобождается только когда исчезает последняя ссылка. Значит delete обязан
снять **обе** стороны.
Связано: drafts/logical-title-model.md §5.3/§6.4, ADR-2026-06-13-hardlinks, specs/architecture.md, specs/workflow.md
## Действие «Удалить» (одна загрузка)
- Снять живые хардлинки загрузки (переиспользуем undo-механику: `superseded`
пропускаем) **+** удалить раздачу с файлами из qBittorrent (новый метод в `qbt`,
`deleteTorrents` с `deleteFiles=true`).
- **Осознанно обходим** предохранитель последней копии (undo при «источник удалён,
цель — последняя копия» отказывает — `worker/review.go:499`; здесь мы наоборот
хотим снять последнюю копию).
- Обязательное **подтверждение** — это выход за инвариант «источник
неприкосновенен», не по случайному клику. Логировать как осознанное удаление
источника.
## undo vs delete (зафиксировать различие)
- **undo** — «перераспознать»: снимает только наши ссылки, раздачу в qBittorrent
сохраняет, данные бережёт (гард включён). Уже готов.
- **delete** — «убрать окончательно, освободить место»: снимает наши ссылки И
сносит раздачу+файлы, гард выключен, состояние терминальное.
## Терминальное состояние
Переиспользуем существующий `deleted` (исход тот же: и источник, и цель сняты) —
**без** нового статуса. Инициатора (`user` против reconciliation) пишем в причину/
лог перехода. В граф переходов добавить явное пользовательское ребро
`done → deleted` (сейчас `deleted` выводит только сверка с реальностью).
## Опционально (если понадобится)
Мультивыбор в списке + «удалить выбранное» — тонкая обёртка над тем же действием
для редкого случая «снести сериал целиком». Вычисляемую группу-«тайтл» и экран
состава **не** делаем — оверинжиниринг ради редкого сценария.
Оформить как OpenSpec-change (дельта `state-reconciliation`/`review` + метод `qbt`
+ ребро графа + action в UI/боте).
Связано: drafts/logical-title-model.md §5.3/§6.4, ADR-2026-06-13-hardlinks,
openspec/specs/state-reconciliation, specs/workflow.md, пакеты qbt, worker, layout.