Беклог + чистка: две находки аудита в беклог, поправлен устаревший комментарий

Аудит capability после пачки lifecycle-задач вскрыл две пред-существующие
находки (вне scope самих задач) — заведены в беклог:
- catched-source-type-namer-okno (средний): addReq не пересобирается из свежего
  source_type в окне namer'а; самоисцеляется через magnet_timeout→Retry.
- dismiss-cancel-user-dismiss-marker (низкий): веб-UI зовёт Cancel вместо Dismiss
  на не-терминальных, теряется маркер user_dismiss.

Инлайн: finishRecognition — комментарий врал про «Ф3, авто-раскладки нет»;
фактически авто-раскладка идёт при Decision.Auto.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
av
2026-07-18 08:44:36 +03:00
co-authored by Claude Opus 4.8
parent 659fa5ec44
commit 50f29b56aa
4 changed files with 110 additions and 2 deletions
@@ -0,0 +1,47 @@
# Веб-UI зовёт Cancel вместо Dismiss на не-терминальных → теряется `user_dismiss`
**Приоритет:** низкий · **Теги:** review-2026-07-17, state-reconciliation
Найдено аудитом capability **state-reconciliation** (сверка код↔спека).
Пред-существующее, вне scope пачки lifecycle-задач.
## Суть
Спека `openspec/specs/state-reconciliation/spec.md` (требование «Ручное
закрытие»): команда `dismiss` доступна из **любого** состояния кроме `deleted`
**во всех транспортах**, и переход SHALL помечаться `error_code = user_dismiss`.
В веб-UI danger-zone «Закрыть» (dismiss) гейтится только для терминальных
состояний: `Dismissable = IsTerminal() && !deleted && !cancelled`
(`internal/httpapi/download.go:130`, шаблон
`web/templates/partials/download_main.html:99-112`). Для НЕ-терминальных
(`stuck`, `deferred`, `downloading`, `review`) закрытие в UI идёт кнопкой
«Отменить» → `Cancel` (`internal/worker/worker.go:973`), которая пишет **пустой**
`error_code`, а не `user_dismiss`.
## Насколько больно
Функционально сценарии проходят: `Cancel` тоже даёт `cancelled` и не трогает
файлы/раздачу, семантика для пользователя идентична. Состояния без доступного
«закрытия» нет (кроме `deleted`/`cancelled`). Теряется только маркер
`user_dismiss` в `error_code` — расхождение с буквой спеки и небольшая потеря
наблюдаемости (в аналитике/логах не отличить «пользователь закрыл активную» от
«пользователь отменил»). Отсюда низкий приоритет.
## Развилка (решить до кода)
- **A — привести код к спеке:** веб-UI на не-терминальных тоже зовёт `Dismiss`
ради единого маркера `user_dismiss`; либо `Cancel` пишет `user_dismiss`.
- **B — привести спеку к коду:** зафиксировать осознанное разделение (`Cancel`
для активных, `Dismiss` для терминальных) — уточнить требование, что стоп-кран
на не-терминальных реализуется `Cancel`'ом, и определить, какой `error_code`
ожидается.
Сначала решить, осознанно ли разделение Cancel/Dismiss; если да — вероятно B.
## Ссылки
- `internal/httpapi/download.go:130` — гейт `Dismissable`
- `web/templates/partials/download_main.html:99-112` — danger-zone
- `internal/worker/worker.go:973``Cancel`; `:1001``Dismiss`
- `openspec/specs/state-reconciliation/spec.md` — требование «Ручное закрытие»