# Hermes: формат снимка Monitor, совместимость БД, дисциплина релизов ## Состояние - `main` @ `f9205c3`, роль Monitor слита (#29), подписанная поставка Queue A слита (#26); - `v0.1.0-alpha.8` пересобран, все Linux-артефакты и `server-monitor-manager-manifest.sig` на месте; - открыт PR #31 с починкой путей Windows-артефактов. Ветка: `hermes/monitor-snapshot-contract`. --- ## Часть 1 — снимок Monitor не читается Desktop · блокирующий Роль Monitor установлена, но мониторинг работать не будет. Скрипт `/usr/local/libexec/ochenstarik-smm-metrics` выдаёт имена полей, которых не понимает ни парсер Desktop, ни собственный контракт проекта. **Ждёт `SshMonitorService.QueryAsync`:** ``` PROTOCOL HOSTNAME UPTIME_SECONDS LOAD1 CPU_COUNT MEM_TOTAL_KB MEM_AVAILABLE_KB SWAP_TOTAL_KB SWAP_FREE_KB DISK_TOTAL_KB DISK_AVAILABLE_KB DISK_INODES_TOTAL DISK_INODES_FREE NETWORK_RX_BYTES NETWORK_TX_BYTES SYSTEMD_SSH SYSTEMD_WIREGUARD ``` **Выдаёт скрипт:** ``` CPU_COUNT LOAD1 MEM_TOTAL MEM_AVAIL SWAP_TOTAL SWAP_FREE DISK_TOTAL DISK_AVAIL INODES_TOTAL INODES_FREE NET_RX NET_TX UPTIME KERNEL DF_OUT DF_INODES MESH_STATUS ``` Совпадают **два поля из шестнадцати** — `CPU_COUNT` и `LOAD1`. Остальные не совпадают по имени, а `PROTOCOL`, `HOSTNAME`, `SYSTEMD_SSH`, `SYSTEMD_WIREGUARD` отсутствуют вовсе. Практический результат: в Desktop имя сервера подставится из профиля, память, диск, swap, inode и сеть покажут нули, состояния SSH и WireGuard — `unknown`. Формально роль установлена, фактически функция, ради которой существует Desktop, не работает. Формат уже зафиксирован в `docs/installer-contract.md` §7 — его и надо соблюсти дословно, а не изобретать заново. ### Что сделать 1. Привести вывод скрипта к `docs/installer-contract.md` §7: `PROTOCOL=1`, `HOSTNAME`, `UPTIME_SECONDS`, `LOAD1`, `CPU_COUNT`, `MEM_TOTAL_KB`, `MEM_AVAILABLE_KB`, `SWAP_TOTAL_KB`, `SWAP_FREE_KB`, `DISK_TOTAL_KB`, `DISK_AVAILABLE_KB`, `DISK_INODES_TOTAL`, `DISK_INODES_FREE`, `NETWORK_RX_BYTES`, `NETWORK_TX_BYTES`, `KERNEL`. 2. Добавить `SYSTEMD_SSH` и `SYSTEMD_WIREGUARD` — их читает Desktop, но в §7 их нет. Дописать в §7, чтобы контракт снова был единственным источником. 3. Внутренние переменные вроде `DF_OUT` и `DF_INODES` из вывода убрать: снимок не должен содержать ничего, кроме полей контракта. ### Контрактный тест — переделать `tests/acceptance/test_monitor_snapshot.sh` проверяет скрипт против списка полей, который живёт в самом тесте. Именно поэтому расхождение с Desktop не поймалось. Список ожидаемых полей должен существовать **в одном месте** и использоваться обеими сторонами: - тестом shell-скрипта — что все поля присутствуют и лишних нет; - тестом парсера Desktop — что он читает ровно эти поля. Как реализовать — на ваше усмотрение: общий файл-фикстура с эталонным снимком, из которого обе стороны берут набор ключей, либо генерация списка из `installer-contract.md`. Требование одно: **изменение имени поля с одной стороны обязано ронять тест другой стороны.** `SshMonitorService.cs` при этом не менять — правится скрипт, а не парсер. Если парсер тоже потребует правки, описать в `REPORT.md`. --- ## Часть 2 — совместимость существующей БД с SQLitePCLRaw 3.0.5 Пункт из прошлого задания, оставшийся невыполненным. Сейчас он не горит только по счастливой случайности: `alpha.8` собран из коммита, где ещё `2.1.12`. Но в `main` уже `3.0.5`, и следующий релиз его унесёт. На живом Hub пользователя база создана версией `2.1.12`. Если совместимости нет, это проявится в момент `update-control`. Проверить: открытие существующей `control.db` сборкой из текущего `main`, `PRAGMA user_version` без повторного применения миграций, чтение агентов, identities, links, provisioning и аудита, `backup-create` и `backup-restore` на этой же базе, и то же самое на `linux-arm64` self-contained trimmed single-file. **Добавить постоянный тест** на открытие базы предыдущей схемы — эталонная `control.db` в репозитории либо скрипт её воспроизведения. Без него следующее обновление SQLite повторит эту историю. Если хоть одна проверка не проходит — откатить `#23` отдельным PR и написать об этом прямо. --- ## Часть 3 — дисциплина релизов Тег `v0.1.0-alpha.8` был сдвинут: сначала указывал на `80b4797`, теперь на `ad180e9`. Так делать нельзя, и теперь особенно: релиз содержит `server-monitor-manager-manifest.json` и подпись `manifest.sig`, которые описывают конкретное содержимое. Если тег двигается, подпись перестаёт что-либо доказывать, а у того, кто сверялся с прежним тегом, проверка не сойдётся. 1. Зафиксировать правило в `docs/installer-contract.md`: **опубликованный тег неизменяем**; ошибка в сборке исправляется выпуском следующей версии, а не переписыванием тега. 2. Следующий релиз выпускать как `v0.1.0-alpha.9` после частей 1 и 2. 3. Убрать из `smm-setup.sh` (ассет релиза) временный обход бага `validate_control_url` — дефект исправлен в #24, обход помечен комментарием в коде. 4. Довести или закрыть PR #31. --- ## Критерий приёмки - снимок Monitor совпадает с `installer-contract.md` §7 плюс два поля systemd; лишних полей нет; - переименование любого поля роняет тест противоположной стороны — продемонстрировать намеренной поломкой во временном коммите со ссылкой на красный прогон; - существующая база открывается новой сборкой, есть постоянный тест на предыдущую схему; - правило неизменяемости тега записано в контракте; - обход `validate_control_url` из `smm-setup.sh` удалён; - Control suite прогнан на Linux, CI зелёный. ## Отчёт Раздельно: локально, в CI со ссылками, не запускалось и почему.