specs: в state-reconciliation разведены Cancel и Dismiss по состояниям
- требование «Ручное закрытие загрузки» приведено к коду: два пути закрытия, error_code на каждом, раскладка поверхностей — описательно, а не SHALL - уборка своего торрента после отмены названа исключением по состоянию, а не по команде; убрана ложная гарантия «данных пользователя не касается» - в docs/review.md записан проскочивший дефект гарда окна после add и новый вопрос проходу adversary про асимметрию признака владения
This commit is contained in:
+40
-1
@@ -109,6 +109,10 @@ Go-сервиса и что здесь уже проскакивало. Устр
|
||||
- `adversary`: что даёт крафт-магнет с чужим или подставным инфохэшем —
|
||||
присоединение к чужой активной загрузке, отравление владения?
|
||||
(открытая задача про идентичность инфохэшей)
|
||||
- `adversary`: где признак «это наше» снимается с одной сущности, а действие
|
||||
применяется к другой — присутствие раздачи в qBittorrent против байтов на
|
||||
диске, запись в БД против файла, инфохэш против содержимого? (журнал,
|
||||
2026-08-06: уборка своего торрента сносила чужие файлы)
|
||||
- `ops`: что делает эта ветка, когда qBittorrent недоступен несколько минут
|
||||
подряд — сколько ERROR-строк в секунду и меняется ли состояние задач?
|
||||
(задача про ERROR-шторм фоновых циклов)
|
||||
@@ -205,7 +209,42 @@ merge-раскладка при повторном добавлении разд
|
||||
|
||||
### Записи
|
||||
|
||||
Пока пусто. Журнал заведён 2026-07-23 вместе с переработкой конвейера
|
||||
Журнал заведён 2026-07-23 вместе с переработкой конвейера
|
||||
([ADR-2026-07-23-review-pipeline-generative](adr/ADR-2026-07-23-review-pipeline-generative.md));
|
||||
случаи до этой даты не восстанавливались — восстановленная постфактум причина
|
||||
непоймания недостоверна, а именно она и нужна.
|
||||
|
||||
## 2026-08-06 — уборка своего торрента после отмены сносит чужие файлы [проскочил]
|
||||
|
||||
- **Где:** `internal/worker/worker.go:501-556` — гард `:501-509`, удаление
|
||||
`:550`. Норма — `openspec/specs/download-tracking/spec.md`, требование
|
||||
«Добавление пойманной загрузки в qBittorrent».
|
||||
- **Симптом:** найден проходом `adversary` на ревью задачи
|
||||
`dismiss-marker-lost` (2026-08-06), не в эксплуатации. В проде не всплывал.
|
||||
- **Причина:** гард «подтверждённое отсутствие непосредственно перед `add`»
|
||||
подтверждает отсутствие **записи торрента** в qBittorrent, но не отсутствие
|
||||
**данных** на диске. Пользователь, снявший раздачу из qBittorrent с
|
||||
сохранением файлов (`download-tracking` сама предписывает это как способ
|
||||
восстановления зависшей magnet-раздачи), и подавший тот же торрент заново,
|
||||
получает `add`, подхватывающий пред-существующие файлы. Отмена в окне между
|
||||
re-read и `PromoteCatched` даёт `torrents/delete` с `deleteFiles=true` по
|
||||
этим файлам. Исключение инварианта «источник неприкосновенен» покрывает
|
||||
«собственный торрент», а признак «своё» подменён на «торрента не было».
|
||||
- **Чем воспроизведён:** тестом на фейковом клиенте qBittorrent во временном
|
||||
каталоге прогона (`tmp/`, не сохранён): `Cancel` в окне после `add` вызывает
|
||||
`Delete(hashes, deleteFiles=true)` при живом файле под `paths.downloads`,
|
||||
созданном до `add`. Тот же путь достижим через `Dismiss` — гейт `Dismiss`
|
||||
шире, а уборка срабатывает по состоянию (`after.State != catched`), а не по
|
||||
команде. **Не прогонялся** последний шаг — что боевой qBittorrent по
|
||||
`deleteFiles=true` физически сносит пред-существующий контент: в бой ходить
|
||||
запрещено, отсюда `Confidence: medium`.
|
||||
- **Почему не поймали:** окно после `add` разбиралось как **гонка** (кто
|
||||
успел — отмена или промоушен) и проверялось на «не удалим ли чужой торрент».
|
||||
Вопрос «а если торрента нет, но данные есть» не задавал никто: ни один
|
||||
проход не спрашивал про **асимметрию признака владения** — признак снимается
|
||||
с одной сущности (запись в qBittorrent), а действие применяется к другой
|
||||
(байты на диске). Враждебный проход до этой задачи на данном коде не гонялся.
|
||||
- **Что меняем:** вопрос `adversary` в разделе выше дополнен пунктом про
|
||||
асимметрию признака владения. Сам дефект — задачей в беклоге, кандидат
|
||||
`critical`; спека `state-reconciliation` в том же изменении перестала
|
||||
утверждать, что уборка «данных пользователя не касается».
|
||||
|
||||
Reference in New Issue
Block a user