diff --git a/agents/inbox/2026-09-02-A59-visible-update.md b/agents/inbox/2026-09-02-A59-visible-update.md new file mode 100644 index 0000000..7e0687b --- /dev/null +++ b/agents/inbox/2026-09-02-A59-visible-update.md @@ -0,0 +1,151 @@ +# Задание 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`.