# Antigravity: доказать проверку подписи на стороне Desktop

## Состояние

`main` @ `b0ad40c`, открытых PR нет, одна ветка, CI зелёный. Ваша работа по очереди B и проверке релиза вошла в `main` в составе PR #41.

Ветка: `antigravity/desktop-update-proof`.

---

## Зачем

`UpdateService` умеет проверять подпись manifest перед обновлением: identity подписи вшита константой, при несовпадении хэша или подписи обновление отклоняется. Тесты к нему есть — но все они работают на **синтетических** данных, которые тот же код и порождает.

Ни один тест не подаёт `UpdateService` **настоящий** manifest, настоящую подпись и настоящий сертификат из опубликованного релиза. То есть проверено, что код отвергает то, что мы сами испортили, и не проверено, что он принимает то, что реально выпускается.

Ровно этот разрыв уже дважды дорого стоил. Проверка релиза на стороне Linux падала не из-за логики, а из-за имени ассета и отсутствующего сертификата — вещей, которые синтетические данные не воспроизводят. На стороне Windows такой проверки нет вовсе.

## Что сделать

Тест, который берёт материал из настоящего релиза и прогоняет через `UpdateService`.

1. **Приёмочный тест против опубликованного релиза.** Скачать `server-monitor-manager-manifest.json`, `.sig` и `.pem` тега `v0.1.0-alpha.14` публичным `curl` — без `gh` и без токена, как это делает Desktop у пользователя, — и убедиться, что `UpdateService` принимает их и извлекает ожидаемую версию и хэши.

   Тег задать параметром с умолчанием, чтобы прогон не привязывался к одному релизу навсегда.

2. **Негативные случаи на том же материале**, а не на сгенерированном: подменённый хэш в настоящем manifest; настоящий manifest с подписью от другой identity; отсутствующий сертификат; сертификат от другого workflow. Все четыре — отказ.

3. **Сетевой тест не должен ронять обычный прогон.** Пометить его категорией и включать отдельно — в `windows-build.yml` шагом, который явно её запускает. Разработчик без сети должен получать зелёный основной набор.

4. **Проверить, что Windows CI действительно исполняет эти тесты.** Сейчас `Test Desktop security` запускает проект целиком; убедиться, что новая категория в него попадает, а не отфильтровывается молча. Продемонстрировать намеренной поломкой: испортить ожидаемую identity, показать красный прогон, откатить.

## Границы

Hermes выпускает `v0.1.0-alpha.14` и добавляет в `deploy/smm-setup.sh` команды `install-hub` и `install-node`. Он же правит `docs/linux-bootstrap.md` и `docs/release-policy.md`.

**Не трогать:** `deploy/**`, `.github/workflows/linux-*.yml`, `.github/workflows/release-verification.yml`, `tests/release-verification/**`, `docs/**`.

Ваша область: `src/ServerMonitorManager.Desktop/UpdateService.cs`, `tests/ServerMonitorManager.Desktop.Security.Tests/**`, и при необходимости шаг запуска тестов в `.github/workflows/windows-build.yml` — этот файл Hermes сейчас не трогает, но изменение согласовать в отчёте.

Задача зависит от выпуска alpha.14. До его публикации можно писать тесты против `v0.1.0-alpha.9`, но окончательный прогон — против alpha.14: это первый релиз, где сертификат публикуется и подпись проверяема целиком.

## Критерий приёмки

- тест принимает настоящий manifest, подпись и сертификат опубликованного релиза;
- четыре негативных случая на настоящем материале отвергаются;
- сетевые тесты отделены категорией и не ломают офлайн-прогон;
- Windows CI их исполняет — подтверждено намеренной поломкой со ссылкой на красный прогон;
- загрузка идёт публичным `curl`, без `gh` и без токена;
- `git diff --name-only main` не выходит за границы;
- CI зелёный, PR не смержен.

## Отчёт

Раздельно: локально, в CI со ссылками, не запускалось и почему. Если тест против настоящего релиза обнаружит расхождение — вынести отдельным разделом, это результат, а не помеха.

---

## Доработка PR #55 — отделить сетевые тесты в workflow

Проверено 2026-08-18. Выполнено почти всё, и выполнено хорошо:

- приёмочный тест берёт настоящие manifest, подпись и сертификат опубликованного релиза публичным HTTP, без `gh` и без токена;
- четыре негативных случая на настоящем материале отвергаются;
- исполнение в Windows CI **доказано намеренной поломкой** со ссылкой на красный прогон 32049692162 и на зелёные после отката. Это ровно то, что требовалось пунктом 4, и это первый в проекте отчёт, где утверждение об исполнении подкреплено падением;
- границы соблюдены: один файл.

**Не выполнен пункт 3.** Требовалось: пометить сетевые тесты категорией **и включать их отдельным шагом в `windows-build.yml`**, чтобы разработчик без сети получал зелёный основной набор. Категория `[Trait("Category", "LiveRelease")]` проставлена, но `.github/` в PR не изменён вовсе. Следствия:

- шаг `Test Desktop security` по-прежнему запускает проект целиком, поэтому **каждый** прогон Windows CI теперь зависит от доступности github.com. При проверке этого PR GitHub отдавал `HTTP 503` — то есть отказ внешней службы покрасит основной гейт на изменениях, не имеющих к релизам никакого отношения;
- разработчик без сети получает красный набор, если не вспомнит про флаг `--filter Category!=LiveRelease`. Требование было противоположным: зелёный по умолчанию.

Сделать в `windows-build.yml` два шага вместо одного:

1. `Test Desktop security` — `dotnet test ... --filter Category!=LiveRelease`. Основной гейт, без сети;
2. `Test Desktop security (live release)` — `dotnet test ... --filter Category=LiveRelease`. Сетевой, обязательный, но отделённый: по его падению сразу видно, что дело в релизе или в сети, а не в логике.

`windows-build.yml` в запрещённый список не входит — пункт 3 прямо предписывал его изменить.

**Отдельно, на ваше решение.** Тег зафиксирован как `v0.1.0-alpha.14` с переопределением через `SMM_TEST_RELEASE_TAG`. С тех пор вышли alpha.15–18, и проверка релиза в CI зелёная против alpha.18. Тест доказывает, что проверяется релиз четырёхдневной давности, а не тот, который получают пользователи. Разумно передавать в шаге live-release текущий тег, оставив значение по умолчанию как есть. Если считаете, что фиксация на заведомо годном релизе важнее, — напишите это обоснованием в отчёте, но тогда нужен способ узнать, что новый релиз перестал проходить desktop-проверку.
