# Antigravity: закрыть PR #25 и сделать подписанную поставку

## Часть 1 — довести PR #25 до merge

Ветка `antigravity/cert-lifecycle`, PR #25, CI 14/14.

Четыре из пяти пунктов прошлого задания закрыты правильно. Отдельно отмечу проверку на trimmed-артефакте: сделана именно так, как требовалось — `Control__ClientCertificateDays=999` переменной окружения на linux single-file, с подтверждённым отказом старта. Плюс обратный тест `CertificateDays45_IssuesCertificateWith45DaysValidity`. Дублирующий эндпоинт удалён, `TEST_EVIDENCE.md` из репозитория убран.

Осталось одно:

**Ребейз на текущий `main` (`df4dfd1`).** Ветка стоит на `80b4797` — до шести merge от dependabot. Сама она workflow и lock-файлы не трогает, поэтому откатить ничего не откатит, но её зелёный CI прогонялся на **старом наборе зависимостей**. Связка «изменения сертификатов + SQLitePCLRaw 3.0.5» вместе не проверялась.

После ребейза дождаться зелёного CI и слить.

⚠️ Hermes параллельно проверяет совместимость существующей базы с SQLitePCLRaw 3.0.5. Если он найдёт несовместимость и откатит #23 — ребейзить придётся заново. Согласуйте момент.

---

## Часть 2 — подписанная поставка

Пункт Горизонта 0. Ваша область по факту предыдущих задач: CI, workflow, цепочка поставки.

### Зачем

Сейчас bootstrap сверяет `ARCHIVE.sha256`, лежащий рядом с архивом **в том же релизе**, а manifest не подписан и содержит только хэш самого bootstrap. Кто может опубликовать релиз — ставит произвольный код с правами root на весь парк через `update-agent`. Воспроизводимость сборки вы уже закрыли; без подписи она остаётся половиной решения.

### Разграничение с Hermes — важно

Hermes ведёт роль Monitor и правит **`deploy/ochenstarik-server-monitor-manager.sh`**. Это же файл, где живёт `verify_archive`.

Поэтому задача делится на две очереди:

**Очередь A — начинать сразу, bootstrap не трогает:**

1. **Manifest v2** в release-workflow: хэши всех артефактов (bootstrap, оба `tar.gz`, MSIX, SBOM), версии Control/Agent/helper/Desktop, минимальные совместимые версии, `helper_protocol`. Сейчас manifest содержит только хэш bootstrap.
2. **Подпись manifest.** `cosign sign-blob` в keyless-режиме через OIDC GitHub Actions — предпочтительно, приватный ключ хранить не нужно. Альтернатива `minisign` с ключом в secrets. Подпись выкладывать ассетом релиза.
3. **Негативные тесты в CI**: изменённый байт в архиве, подменённый хэш в manifest без переподписи, manifest без подписи — все три должны отвергаться. Тесты писать против отдельного скрипта-верификатора, не против bootstrap.
4. `PROGRAM_VERSION` подставлять из тега при упаковке вместо `0.2.0-dev`.

**Очередь B — после merge роли Monitor:**

5. `verify_archive` в bootstrap сверяет хэш **с manifest**, а не с соседним `.sha256`; старый путь только под явным `SMM_ALLOW_UNSIGNED=1` с громким предупреждением.
6. Новое действие `verify-manifest MANIFEST SIGNATURE`.
7. Публичный ключ или OIDC-identity **вшить константой** в bootstrap и Desktop — не скачивать вместе с релизом, иначе подпись бессмысленна.
8. Отказ `update-control` и `update-agent` при несовместимой паре версий — требование `docs/installer-contract.md` §6, невыполненное до сих пор.
9. Отсутствие инструмента проверки подписи — отказ, а не предупреждение.

Очередь A — отдельный PR, очередь B — отдельный. Не смешивать.

### Чего опасаться

Release-workflow **не запускаются на pull request**: они триггерятся тегом и `workflow_dispatch`. Ваш зелёный PR ничего не докажет про них — вы уже дважды на этом обжигались, с `permissions` в PR #14 и с `locked-mode` в PR #15.

Поэтому обязательно:

- `actionlint` на все пять workflow, вывод в отчёт;
- прогон через `workflow_dispatch` на своей ветке. Шаги публикации защищены `if: startsWith(github.ref, 'refs/tags/')` и на ветке пропускаются, но разбор файла и генерация manifest выполнятся — этого достаточно, чтобы поймать ошибки схемы и логики.

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

- manifest содержит хэши всех артефактов и версии компонентов;
- manifest подписан, подпись выложена ассетом;
- три негативных теста зелёные;
- `actionlint` чист на всех пяти workflow, вывод приложен;
- `workflow_dispatch`-прогон на ветке выполнен, ссылка в отчёте;
- `deploy/ochenstarik-server-monitor-manager.sh` в очереди A не изменён — проверяется `git diff --name-only main`;
- PR не смержены.

## Отчёт

Раздельно: локально, в CI со ссылками, не запускалось и почему. Описание PR заполнять после завершения CI.
