# 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.