# Задание A61: установщик и релизный конвейер — проверка на настоящей машине ## Для кого **agy** (машина владельца, Windows, реальные учётные данные и `agy`). Не для серверной сессии: у неё нет `csc.exe`, нет Windows-реестра, нет прав публиковать релиз от имени владельца. Ревьюер (сессия на ПК) принимает. ## Дата поступления 2026-09-03 ## База `origin/main` (`89435ea`). ``` git fetch origin --prune git checkout -b installer/a61-live-verification origin/main ``` В `main` напрямую не пушить. --- ## Задача HUB-1 довёл CI до зелёного на Windows и Linux и закрыл дыру в релизных воротах: `release_gate.py` перестал заявлять проверку хеша, которой не было, и перестал быть fail-open при обрыве сети или 404. Заодно нашлось — и осталось непроверенным вживую, потому что для этого нужна настоящая Windows-машина, а не CI-раннер: Установщик — единственный способ, которым продукт попадает к владельцу, и он **не проверяется нигде за пределами CI-раннера**, который сам его никогда не собирает. Ни один прогон `pytest -m installer` не выполнялся на настоящей установке. Ни один релиз ещё не прошёл через конвейер целиком — все прошлые теги падали на `Release Gate Check` (см. `agents/done/2026-09-02-HUB1-audit-p0-green-main.md`, раздел «Найдено сверх задания»), а действующие релизы на GitHub собраны и выложены вручную, мимо `release.yml`. Это задание не про код хаба — про то, что установщик и конвейер публикации делают на реальной машине то же, что декларируют. --- ## Что уже проверено — заново не выяснять ### CI зелёный, но установщика не касается `pyproject.toml`: ``` addopts = "-m 'not live and not network and not installer'" ``` Три теста в `tests/test_installer.py`, помеченные `@pytest.mark.installer` (`test_setup_exe_exists`, `test_silent_installer_execution_with_hermes`, `test_silent_installer_fails_without_hermes`), **исключены из каждого прогона** по умолчанию, и ни в `.github/workflows/ci.yml`, ни в `release.yml` нет шага, который передавал бы `-m installer` явно. К тому же все три сами пропускают себя (`pytest.skip`), если `dist/HermesHubSetup.exe` не собран — а его никто не собирает ни в CI, ни в конвейере релиза. `tests/test_installer_windows_and_linux.py::test_windows_csharp_launchers_and_setup_compile` пропускается в CI с `csc.exe compiler not found in standard .NET Framework location` — компилятор ищется по путям `C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe` и `...\Framework\v4.0.30319\csc.exe`; на `windows-latest` раннере GitHub его нет. На обычной Windows 10/11 он есть — так и написано в `installer/README.md`: «compiles `HermesHubSetup.cs` using standard .NET Framework `csc.exe` present on all Windows 10/11 machines without extra toolchains». ### Тесты уже изолированы от твоего реестра `test_silent_installer_execution_with_hermes` и `test_silent_installer_fails_without_hermes` подставляют `HERMES_HOME`, `LOCALAPPDATA`, `APPDATA`, `USERPROFILE` во временный каталог и ставят `HERMES_HUB_NO_REGISTRY=1` — это отключает запись в `HKCU\...\Uninstall` (закрыто ещё в A4, см. `agents/done/2026-08-21-A4-antigravity-credential-isolation.md`). Прогон этих тестов не трогает твой реальный реестр и твою реальную установку. `installer/README.md` отдельно требует того же: «Unit Tests: Must NEVER modify user Windows Registry or Start Menu shortcuts» — этому требованию тесты уже следуют, проверить нужно исполнением, а не читать код на слово. ### Релиз ещё никогда не публиковался этим конвейером `gh run list --workflow=release.yml` на момент HUB-1 показывал failure на всех пяти последних тегах, включая `v0.1.3-b1` — падение на `Run Release Gate Check`, той же причине, что красила CI. HUB-1 эту причину устранил, но **ни разу после починки конвейер не запускался** — значит и новые шаги (`Built assets must be installable by the updater`, `Publication Gate (published release must be verifiable)`, оба добавлены в HUB-1) ни разу не выполнялись на настоящем прогоне GitHub Actions, только локально функциями напрямую. --- ## P0-1. Собрать установщик и прогнать installer-тесты на настоящей машине 1. Собрать: `installer/build_installer.ps1` (компилирует `HermesHub.cs`, `HermesHubWeb.cs`, `HermesHubSetup.cs` через `csc.exe`, кладёт `dist/HermesHubSetup.exe`). Приложить вывод сборки. 2. Прогнать три `installer`-теста явно, отдельно от общего набора: ``` pytest -m installer tests/test_installer.py -v ``` Все три должны выполниться (не `SKIPPED`) и пройти. Приложить полный вывод. 3. Прогнать `test_windows_csharp_launchers_and_setup_compile` отдельно — на твоей машине `csc.exe` должен найтись. Приложить вывод; если и здесь `SKIPPED` — назвать точный путь, по которому компилятор искался и не нашёлся, и где он есть на самом деле. 4. **Подтвердить исполнением, что реестр не тронут**: снять состояние `HKCU\Software\Microsoft\Windows\CurrentVersion\Uninstall\HermesHub` до и после прогона (`reg query`), приложить оба вывода. Совпадают — тесты не соврали про изоляцию. ## P0-2. Полный цикл `/silent` на реальной установке 1. Установить через `dist/HermesHubSetup.exe /silent` в **реальный** (не временный) профиль — как ставит владелец. 2. Проверить коды возврата по правилу из `agents/AGENTS.md` §4: `0`, `10`, `11`, `12` — на тех сценариях, для которых они определены (обычная установка, установка без Hermes Agent, повторная установка, откат). Каждый код — с описанием сценария, который его вызвал. 3. После установки — обычный рабочий цикл: хаб запускается, видит существующие профили `agy`, ничего не потеряно. Если что-то потерялось — это находка, а не повод откатывать проверку молча. 4. **Не удалять существующие профили и учётные данные для эксперимента.** Если для чистоты нужна отдельная установка — использовать переменные изоляции (`HERMES_HOME` и т.д.), как это уже делают тесты, а не боевой каталог. ## P0-3. Один настоящий прогон релизного конвейера — без публикации владельцу Цель — увидеть, что новые шаги `release.yml` (Release Gate → сборка → проверка пригодности ассетов → публикация → Publication Gate) действительно отрабатывают на GitHub Actions, а не только в теории. 1. **Не создавать публичный релиз без отдельного разрешения владельца.** Вместо реального тега: либо (а) временный форк/ветка с ручным запуском `workflow_dispatch`, если конвейер его поддерживает — иначе не добавлять `workflow_dispatch` ради этого задания, это отдельное решение; либо (б) прогнать шаги локально в том порядке, в котором их вызывает `release.yml`: ``` python scripts/release_gate.py # сборка через build_installer.ps1 в dist/ python scripts/release_gate.py --assets dist ``` и явно объяснить, что осталось непроверенным без настоящей публикации (шаг `Publish GitHub Release` и `--publication-only` после него). 2. Если владелец в диалоге явно разрешит настоящий тестовый тег — тогда можно довести до конца, включая `release_gate.py --publication-only` на опубликованном релизе. **Без этого разрешения — не пушить тег.** 3. Итог — что именно проверено, а что нет и почему (например: «сборка и проверка пригодности ассетов проверены локально в точности как в `release.yml`; публикация и Publication Gate не проверены — нужен реальный тег, разрешения не спрашивал/владелец отказал»). ## P0-4. Проверка исполнением, а не по чтению кода Как и в HUB-1: там, где что-то не запускалось — не писать «должно работать», запустить и приложить вывод. Не удалось — сказать `Н/Д` с точной причиной (например: «на этой машине нет .NET Framework 4.0, только .NET 8» — если это окажется так). --- ## Ограничения - **Не публиковать релиз на GitHub без явного разрешения владельца в этом диалоге.** Прогон `release.yml` через настоящий тег создаёт публичный релиз. - Реальные учётные данные и `~/.hermes/agy_profiles/` не удалять и не менять ради эксперимента; для изоляции — переменные окружения, как в существующих тестах. - Правки ревьюера из `main` не откатывать; правки HUB-1 (P0-1, P0-2 из этого задания опираются на них) не переписывать без причины. - Версию `0.1.3` не понижать и не менять без необходимости. - Правило честности без исключений: неизмеренное — `Н/Д` с причиной. - Если для `workflow_dispatch` нужно менять `.github/workflows/release.yml` — делать это отдельным, явно описанным шагом, не молча. ## Критерии приёмки 1. Ветка в `origin`, `git status` чист. 2. `dist/HermesHubSetup.exe` собран на настоящей Windows-машине; вывод сборки приложен. 3. Все installer-тесты (`pytest -m installer` + компиляция C#) выполнены не как `SKIPPED`; вывод каждого приложен. 4. `HKCU\...\Uninstall\HermesHub` до и после прогона тестов идентичен — оба снятых состояния приложены. 5. `/silent` установка проверена на реальном профиле; коды возврата названы со сценарием каждого. 6. Локальный прогон шагов `release.yml` (Release Gate → сборка → проверка ассетов) воспроизведён и приложен; либо — с явного разрешения владельца — доведён до настоящего тега и `--publication-only`. 7. Каждый непроверенный пункт назван явно, с причиной — не пропущен молча. 8. Отчёт: что собрано, что запущено, точные команды и их вывод, что осталось `Н/Д` и почему. ## Главное HUB-1 сделал ворота честными на уровне кода: они больше не заявляют проверку, которой не было. Это задание проверяет ту же честность на уровне машины — что установщик, который получит владелец, действительно собирается, ставится и обновляется так, как об этом говорит код. Пока это не проверено на настоящей Windows, «зелёный CI» доказывает только код, а не установщик. ## Порядок сдачи Передать точный `FINAL_COMMIT_SHA` и полный вывод всех проверок из P0-1—P0-3.