A59 влит, база задания указана коммитом. Порог тестов поднят с 725 до 740: столько в main после слияния с ветками A58 и A59. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EDLuenXmGjWaS2rs8E72En
12 KiB
Задание A60: обновление доводит себя до конца
Дата поступления
2026-09-02
База
origin/main (2f35377). A59 влит: ветка antigravity/a59-visible-update
принята с исправлениями ревьюера (285ae7c). Показ и загрузку переписывать
второй раз не надо.
git fetch origin --prune
git checkout -b antigravity/a60-update-completes origin/main
В main напрямую не пушить.
Порядок исполнения
Два прохода: Flash реализует, Pro проводит аудит. Пункт P0-5 написан для аудитора.
Зона: применение обновления и перезапуск. Показа и загрузки не касается — там всё принято и проверено.
Что уже сделано — переделывать не надо
A59 довёл обновление до экрана. Ревьюер проверил и принял:
окно при запуске, отказ по версии, молчание без обновлений работает
полоса хода, честное Н/Д без размера работает
отмена с удалением недокачанного файла работает
отмена принимается только на проверке и загрузке работает
SHA-256 обязательна, непроверенный файл не запускается работает
запись о применённом обновлении только после успеха работает
Ничего из этого не трогать.
Задача
Владелец нажимает «Обновить сейчас». Пакет скачивается на глазах, сумма сходится, начинается установка — и на этом всё кончается. Хаб не поднимается, окно гаснет, владелец идёт ставить сборку руками. Ровно то, из-за чего писалось A59.
Разрыв, и он один на обеих системах
Установщик снимает тот процесс, который его запустил и ждёт.
install_latest_update делает так:
stop_running_hub() свои процессы, кроме текущего
subprocess.run(["bash", installer], timeout=600) ЖДЁТ здесь
schedule_restart() сюда управление не доходит
Linux. installer/install-linux.sh:53 в своём stop_running_hub берёт
pgrep -u $(id -u) -f "antigravity_provider.router.web|hermes_hub_web_entry" и не
исключает никого. Под шаблон попадает тот самый питон, который висит на
subprocess.run. Установщик снимает его, schedule_restart не выполняется
никогда, окно прогресса умирает вместе с процессом. Скрипт при этом доживает
сиротой и файлы обновляет — поэтому со стороны выглядит как «поставилось, но не
запустилось».
Windows. installer/HermesHubSetup.cs:280 (StopOwnedRuntime) выглядит
аккуратнее: строит $protected — цепочку собственных предков, чтобы не снять
того, кто его запустил. Но проверка -notin $protected стоит только на
дочерних процессах внутри Stop-HubBranch. Сам процесс-цель снимается
безусловно, а хаб под шаблон antigravity_provider\.router\.web подходит.
Прочитано по коду — подтвердить исполнением, а не поверить на слово.
Отката на путях установщика нет вообще: он есть только для .zip
(apply_update_sync). Ни .sh, ни .exe при срыве на середине ничего не
возвращают.
P0-1. Отсоединённый помощник
Порядок не выдумывать заново — он описан в docstring schedule_restart: сначала
отсоединённый помощник, потом выход текущего процесса. Лаунчер считает хаб
работающим, пока порт отвечает, поэтому поднимать новый, не освободив порт,
бесполезно.
- Хаб порождает помощника (
setsidили отдельная группа процессов на Linux,DETACHED_PROCESSна Windows), передаёт ему путь к уже проверенному пакету и выходит сам, освободив порт. - Помощник: дожидается освобождения порта → запускает установщик → поднимает хаб → завершается.
- Помощник не наследует ни stdout хаба, ни его рабочий каталог: хаб исчезнет раньше, чем помощник закончит.
- Помощник пишет свой ход в файл
~/.hermes/updates/apply-<время>.log, чтобы после неудачи было что показать. Пустой отказ без причины — уже было в A59, второй раз не проходит.
P0-2. Владелец видит, что происходит
- Перед выходом статус
restartingс текстом, что хаб сейчас закроется и поднимется сам. Не «установлено» — установка ещё идёт. - Интерфейс переживает разрыв. Опрос
get_update_progressполучит отказ соединения: это ожидаемое состояние, а не ошибка. Показывать «Hermes Hub перезапускается», продолжать пробовать, при возврате — перечитать страницу. - Не молчать бесконечно. Не поднялся за отведённое время — сказать это прямо и назвать путь к журналу помощника.
P0-3. Откат на путях установщика
- Помощник снимает копию установленного до запуска установщика.
- Установщик вернул не ноль или хаб не поднялся за отведённое время — вернуть прежнее и поднять его.
- Причина отказа — с кодом возврата и хвостом вывода — в журнал и на экран при следующем старте.
- Программа обязана остаться работоспособной. Это главное требование пункта: неудачное обновление не имеет права оставить владельца без хаба.
P0-4. Проверка исполнением
Тестами это не ловится: дело в живом переходе между версиями и в том, кто кого снимает.
- Поставить
v0.1.2-b7, обновиться наv0.1.3-b1через интерфейс. Оба релиза опубликованы, установщики иchecksums.txtна месте. Скриншоты: окно, полоса, экран после возврата. - Замерить время от нажатия до готовности.
- Проверить, что работает новый код — по
running_commit, снятому при старте процесса, а не по номеру версии. - Повторить на Windows.
- Сорвать установку намеренно (испорченный установщик) — проверить откат и что хаб жив.
- Проверить, что старый процесс не остался и порт занят новым.
P0-5. Аудит вторым проходом
- Пройти обновление целиком на обеих системах.
- Проверить, что помощник не снимает чужого — только процессы хаба своего пользователя.
- Проверить откат при сорвавшейся установке и что после него хаб отвечает.
- Проверить, что интерфейс не объявляет успех раньше времени — ни на выходе хаба, ни на разрыве связи.
- Побочные изменения объяснить.
- Пропущенный пункт назвать пропущенным. В A59 живая проверка была пропущена молча, при том что релиз для неё был опубликован за девять часов до сдачи.
Ограничения
- Показ и загрузку из A59 не переделывать.
- Проверку SHA-256 и список разрешённых адресов не ослаблять.
- Показ работающего коммита и времени запуска не ломать.
- Фронтенд без npm, без сборки, без фреймворков — по
docs/web-api/CONTRACT.md§1. - Правки ревьюера из
mainне откатывать — включая комментарии. В A59 сняли шесть блоков с объяснением прошлых регрессий, ревьюер возвращал их руками. - Версию
0.1.3не понижать. - Правило честности без исключений: неизвестное —
Н/Дс причиной, а не правдоподобное число и не полоса во всю ширину.
Критерии приёмки
- Ветка в
origin,git statusчист. - Обновление, запущенное из интерфейса, доходит до работающего нового хаба без участия владельца — на Linux и на Windows, подтверждено скриншотами.
- После перезапуска
running_commitсоответствует новой сборке. - Сорвавшаяся установка откатывается, хаб остаётся работоспособным.
- Старый процесс не остался, порт занят новым.
- Журнал помощника пишется, и при отказе на него указывают.
ruff check .чисто; релизный гейт пройден; тестов не меньше 740.- Отчёт:
START_HEAD,FINAL_HEAD,origin/main,git status,X passed / Y skipped / Z failed, тайминги, скриншоты.
Главное
A59 сделал обновление видимым: владелец видит окно и видит загрузку. Дальше механизм обрывается на самом простом — установщик снимает того, кто его запустил и ждёт результата.
Задание про один шаг: чтобы после нажатия «Обновить сейчас» владелец больше ничего не делал.
Порядок сдачи
Передать точный FINAL_COMMIT_SHA.