# Задание A59: обновление, которое видно и доводит себя до конца ## Дата поступления 2026-09-02 ## База `origin/main` (`58cb88e`). ``` git fetch origin --prune git checkout -b antigravity/a59-visible-update origin/main ``` В `main` напрямую не пушить. ## Порядок исполнения Два прохода: **Flash** реализует, **Pro** проводит аудит. Пункт **P0-7** написан для аудитора. Зона: обновление и перезапуск. С A58 (состояние `agy`) не пересекается. --- ## Задача Владелец показал, как это устроено в Cockpit Tools, и хочет так же: > захожу в программу и независимо от того, работала она или нет, выходит окно об > обновлении. ставишь новую версию (что на линукс, что на винде) — сразу видно > загрузку и что скачивается. потом он останавливает сам все службы, > устанавливает программу новую и запускает. Сейчас владелец ставит каждую сборку установщиком вручную. Обновление внутри программы написано, но не доведено до вида, в котором им пользуются. --- ## Что проверено ревьюером — заново не выяснять Строить с нуля ничего не надо, почти всё уже есть. ``` UpdateManager.check_for_updates есть UpdateManager._download_file есть, с обработчиком хода: content-length и progress_cb(downloaded / total) UpdateManager.download_and_verify есть, с проверкой SHA-256 UpdateManager.install_latest_update есть UpdateManager.schedule_restart есть действия check_updates и apply_update есть в обработчике проверка при запуске сервера есть: server.py вызывает check_for_updates проверка при открытии интерфейса есть: app.js вызывает checkUpdates(true) ``` Три разрыва, и все на виду. 1. **Проверка при запуске молчит.** `checkUpdates(true)` — тихий режим: обновление находится, но владельцу не показывается ничего. 2. **Ход скачивания никуда не идёт.** `progress_cb` в загрузчике есть, но его никто не передаёт и результат не отображается. 3. **Останов служб и запуск после установки** держится на `schedule_restart` и не проверен на обеих системах. Плюс внешнее условие: **лента релизов отстала**. Последний опубликованный — `v0.1.2-b7`, а установлена `0.1.3`. Пока свежий релиз не опубликован, обновлять не на что, и проверить работу нельзя. --- ## P0-1. Окно при запуске 1. **Обновление есть — показывается окно**, а не значок в углу. Независимо от того, работала программа до этого или нет. 2. **В окне: номер версии, что нового, размер загрузки.** «Что нового» брать из описания релиза; нет описания — писать `Н/Д: описание не приложено`, а не пустоту. 3. **Отказаться можно**, и отказ запоминается для этой версии: повторно то же окно не всплывает. 4. **Обновления нет — окна нет.** Молчание при отсутствии новостей. ## P0-2. Скачивание видно 1. **Полоса хода и проценты**, источник — `progress_cb`, он уже написан. 2. **Показывать, что именно скачивается**: имя файла и размер, «сколько из скольких». 3. **Нет `content-length` — так и писать**: `Н/Д: сервер не сообщил размер`, и показывать скачанный объём без процентов. Выдумывать проценты нельзя. 4. **Скачивание можно отменить**, недокачанный файл удаляется. 5. **Проверка SHA-256 остаётся обязательной.** Не сошлась — установка не начинается, файл удаляется, причина на экран. ## P0-3. Установка доводит себя до конца 1. **Останавливаются все свои процессы**: веб-сервер, фоновые опросы, дочерние. Тот же порядок, что в установщике — там это уже сделано в `stop_running_hub`. 2. **Чужого не трогать.** Останавливать только своё: по признаку хаба, в своём пользователе. 3. **Установка и запуск** без участия владельца. После запуска — тот же экран, на котором он был. 4. **Работает на Linux и на Windows.** Разница только в способе запуска, поведение одинаковое. 5. **Сорвалось на середине — откат к прежней версии** и внятное сообщение. Программа обязана остаться работоспособной. ## P0-4. Видно, что обновилось 1. **После перезапуска показать, что версия сменилась**: было — стало. 2. **Строка сборки уже показывает коммит работающего процесса** (`running_commit`, снят при старте) и время запуска. Не ломать: это единственный признак, по которому отличают новый код от старого, пережившего установку. 3. **Событие в журнале** о применённом обновлении с обеими версиями. ## P0-5. Ничего лишнего 1. **Не опрашивать в цикле.** Проверка при запуске и по кнопке. Опрос в цикле уже приводил к тому, что интерфейс сам себя кормил запросами. 2. **Опросы состояния молчат** — они в `SILENT_ACTIONS`, туда же добавить опрос хода загрузки. 3. **Автоматическая установка без спроса запрещена.** Показать, предложить, дождаться нажатия. ## P0-6. Проверка исполнением Тестами это не ловится: дело в живом переходе между версиями. 1. **Обновиться на живой установке** с предыдущей версии на текущую. На обеих системах. Скриншоты окна и полосы хода приложить. 2. **Замерить время** от нажатия до готовности. 3. **Проверить, что после перезапуска работает новый код** — по `running_commit`, а не по номеру версии. 4. **Проверить отказ**: испорченная сумма, обрыв сети, отмена на середине. 5. **Проверить, что старый процесс не остался.** ## P0-7. Аудит вторым проходом 1. **Пройти обновление целиком на обеих системах.** 2. **Проверить, что проценты не выдумываются** при отсутствии `content-length`. 3. **Проверить откат** при сорвавшейся установке. 4. **Проверить, что останавливается только своё.** 5. **Побочные изменения** объяснить. 6. **Пропущенный пункт назвать пропущенным.** --- ## Ограничения - Проверку SHA-256 и список разрешённых адресов не ослаблять. - Показ работающего коммита и времени запуска не ломать. - Фронтенд без npm, без сборки, без фреймворков — по `docs/web-api/CONTRACT.md` §1. - Правки ревьюера из `main` не откатывать. - Версию `0.1.3` не понижать. - Правило честности без исключений: неизвестный размер — `Н/Д` с причиной, а не поддельные проценты. ## Критерии приёмки 1. Ветка в `origin`, `git status` чист. 2. При запуске с доступным обновлением показывается окно; без обновления — не показывается. 3. Отказ от версии запоминается, окно не всплывает повторно. 4. Полоса хода и объём отображаются; без `content-length` — честное `Н/Д` без процентов. 5. Отмена удаляет недокачанный файл. 6. Несовпадение SHA-256 прекращает установку с сообщением. 7. Установка сама останавливает свои процессы, ставит и запускает; проверено на Linux и Windows. 8. Сорвавшаяся установка откатывается, программа остаётся работоспособной. 9. После перезапуска `running_commit` соответствует новой сборке. 10. Опроса в цикле нет; опрос хода загрузки молчалив. 11. `ruff check .` чисто; релизный гейт 10/10; тестов не меньше **708**. 12. Отчёт: `START_HEAD`, `FINAL_HEAD`, `origin/main`, `git status`, `X passed / Y skipped / Z failed`. ## Главное Механизм написан, но им нельзя пользоваться: проверка находит обновление и молчит, ход загрузки считается и никуда не выводится. Владелец из-за этого ставит каждую сборку руками, а сегодня их было десять. Задание не про новый код, а про то, чтобы уже написанное дошло до экрана и довело себя до конца: показать, скачать на глазах, остановить своё, поставить, запустить. ## Порядок сдачи Передать точный `FINAL_COMMIT_SHA`.