## 1. Условие и частота самообновления - [x] 1.1 Завести в домене (`internal/store`, рядом с `IsTerminal`) предикат наблюдаемости: нетерминальные плюс `failed`, `target_missing`, `orphaned`; `done`, `cancelled`, `reverted`, `deleted` — не наблюдаемы. Перечень состояний в `httpapi` не заводить - [x] 1.2 Завести рядом с представлениями две константы интервала — быстрый 5 с (вровень с `[worker].poll_interval`, для поверхности с блоком живых цифр качания) и медленный 15 с — и поле вида, которое отдаёт шаблону выбранный интервал - [x] 1.3 `toView` (`internal/httpapi/httpapi.go`): `SelfPoll` — по предикату наблюдаемости, интервал — быстрый только при `IsDownloading` - [x] 1.4 `buildDownloadView` (`internal/httpapi/download.go`): тот же предикат, интервал всегда медленный — блока прогресса на странице нет ## 2. Шаблоны - [x] 2.1 `card.html`: интервал самополлинга берётся из вида, а не зашит в разметку - [x] 2.2 `progress.html`: снять собственный `hx-get`/`hx-trigger` — партиал остаётся вложенной разметкой карточки без своего опроса - [x] 2.3 `download_main.html`: интервал самополлинга берётся из вида - [x] 2.4 `seeding.html`: снять собственный `hx-get`/`hx-trigger` — секция лежит внутри свопаемого `#download-main` и едет с тиком страницы ## 3. Самообновление не теряет полей полного рендера - [x] 3.1 `handleFragCard` читает размер раскладки через `LayoutSizeByDownload`, как это делает `renderCardFragment`, вместо жёсткого `layoutSize = 0` - [x] 3.2 Отказ тика (`fragErr` и путь «записи нет») отвечает `200` и фрагментом без `hx-*`: объяснение вместо молчаливого застывания и вечного опроса ## 4. Маршруты фрагментов - [x] 4.1 `GET /fragments/downloads/{id}/progress` и `.../seeding` оставить живыми: их партиалы теперь без поллера, поэтому ответ гасит разметку вкладок, открытых до деплоя. В комментарии назвать, что потребителей в новой разметке нет и обработчики убираются отдельной уборкой ## 5. Тесты - [x] 5.1 Карточка наблюдаемой задачи несёт самополлинг на `/fragments/downloads/{id}/card` (включая `failed`, `target_missing`, `orphaned`); карточка `done`, `cancelled`, `reverted`, `deleted` — не несёт ни `hx-get`, ни `hx-trigger` - [x] 5.2 Фрагмент карточки после смены состояния отдаёт новый бейдж и новый набор действий: для `review` — кнопку «Ревью →», для `done` — «Откатить» - [x] 5.3 Карточка в `downloading` содержит ровно одно объявление самополлинга, а вложенный блок прогресса — ни одного; страница сидирующей задачи — ровно одно, а секция «Раздача» — ни одного - [x] 5.4 Интервал в разметке: быстрый у карточки в `downloading`, медленный у прочих наблюдаемых карточек и у страницы в любом состоянии - [x] 5.5 `buildDownloadView`: `SelfPoll` истинен для наблюдаемых состояний и ложен для остальных - [x] 5.6 Фрагмент карточки задачи без раздачи в снимке, но с разложенными файлами показывает размер, а не «—» - [x] 5.7 Тик по несуществующей задаче отвечает `200` фрагментом без `hx-*` ## 6. Документация и приёмка - [x] 6.1 `docs/database.md`: обе константы интервала в таблицу настроек с числовым значением - [x] 6.2 Поведенческая проверка на живом стенде: открыть список, довести раздачу до конца и убедиться, что карточка сама показала переход - [x] 6.3 `openspec validate --strict card-live-refresh` и `task gate` зелёные ## Критерии приёмки (из записи задачи) - [x] К1 Карточка нетерминальной загрузки самополлится, и первый ответ фрагмента после смены состояния несёт новый бейдж (оракул: тест `internal/httpapi` — рендер карточки в `downloading` содержит `hx-get` на `/fragments/downloads/{id}/card`, а подставной читатель, сменивший состояние на `review`, отдаёт карточку с бейджем ревью) - [x] К2 Терминальная карточка себя не опрашивает: фоновых запросов после `done`, `cancelled`, `reverted` и `deleted` нет (оракул: тот же тест — в разметке такой карточки нет ни `hx-get`, ни `hx-trigger`). **Уточнён на чекпоинте:** `failed`, `target_missing` и `orphaned` из перечня выведены — их возвращает в поток фоновая сверка, поэтому они наблюдаются медленным интервалом - [x] К3 Появившееся действие видно без перезагрузки: карточка задачи, перешедшей в `review`, несёт кнопку «Ревью →» (оракул: тест фрагмента карточки) - [x] К4 Страница `/download/{id}` обновляет бейдж и блок действий по тому же правилу, что и карточка (оракул: тест `internal/httpapi/download.go` — `SelfPoll` истинен для наблюдаемых состояний и ложен для остальных) - [x] К5 Правило записано в дельта-спеках обеих затронутых capability (оракул: `openspec validate --strict` и шаг канона в `task gate`) ## Приёмочные критерии из рубрики (ревью дизайна) - [x] Р-1 Стоп-условие совпадает с «дальше само ничего не изменится»: для каждого состояния, где опрос прекращается, названо, что его не двигает ни воркер, ни сверка - [x] Р-2 Финальный тик доставляет новое содержимое до остановки: остановка — свойство уже отданного фрагмента, а не отдельное решение - [x] Р-3 Ровно один поллер на обновляемый корень; корень фрагмента-ответа несёт тот же `id`, что и цель свопа - [x] Р-4 Все поля одного ответа посчитаны из одного чтения: бейдж, действия, цифры и интервал не расходятся между собой - [x] Р-5 Отказ тика определён: что видит человек, продолжается ли опрос, на каком уровне пишется лог - [x] Р-6 Стоимость тика посчитана: что делает один тик и сколько запросов даёт открытая страница и список из N карточек