From 7fac6d5d222ea72731244b5c4945ca085698ffad Mon Sep 17 00:00:00 2001 From: Ochenstarik Date: Thu, 20 Aug 2026 17:38:52 +0700 Subject: [PATCH] =?UTF-8?q?chore(agents):=20=D0=B7=D0=B0=D0=B4=D0=B0=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=20Antigravity=20=D0=BF=D0=BE=20=D0=BC=D0=B5=D1=82?= =?UTF-8?q?=D1=80=D0=B8=D0=BA=D0=B0=D0=BC=20=D1=83=D0=B7=D0=BB=D0=BE=D0=B2?= =?UTF-8?q?=20=D0=B2=20=D0=BA=D0=BE=D0=BD=D1=81=D0=BE=D0=BB=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Windows-клиент показывает CPU, память, диск, задержку и здоровье по каждому серверу, веб-консоль не показывает ничего из этого. Данные при этом уже лежат на Hub: таблица metric_samples наполняется из heartbeat и чистится по MetricRetentionHours, но в группе /api/v1/control нет ни одного маршрута для их чтения. Границей задания зафиксировано то, что переносить нельзя: SSH-терминал и приватные ключи остаются на Windows-машине, это заявленное свойство продукта, а не объём работы. Co-Authored-By: Claude Opus 5 --- .../inbox/2026-08-20-console-node-metrics.md | 110 ++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 agents/antigravity/inbox/2026-08-20-console-node-metrics.md diff --git a/agents/antigravity/inbox/2026-08-20-console-node-metrics.md b/agents/antigravity/inbox/2026-08-20-console-node-metrics.md new file mode 100644 index 0000000..091c1de --- /dev/null +++ b/agents/antigravity/inbox/2026-08-20-console-node-metrics.md @@ -0,0 +1,110 @@ +# Метрики и короткая история узлов в веб-консоли + +- **Кому:** `antigravity` +- **Дата:** 2026-08-20 +- **От кого:** главный агент (`claude`), по задаче владельца «консоль надо + сделать так же, как и Windows-программа» +- **Ветка:** `antigravity/console-node-metrics` +- **Файл отчёта:** `../done/2026-08-20-console-node-metrics.md` + +## Зачем + +Windows-клиент на странице «Серверы» показывает по каждому серверу CPU, +память, диск, задержку, состояние здоровья и статус +(`Pages/ServersPage.xaml`: `CpuText`, `MemoryText`, `DiskText`, +`LatencyText`, `HealthText`, `Status`). Веб-консоль не показывает ничего из +этого: в ней есть только имя узла, состояние, версия агента, время +heartbeat и остаток срока сертификата. + +Это первая из нескольких задач по сближению консоли с Windows-клиентом. +Здесь закрывается ровно метрики и короткая история — остальное перечислено +ниже и в эту задачу не входит. + +## Установленный факт, от которого отталкиваемся + +Данные **уже есть на Hub**, показывать нечем. + +`ControlStore` содержит таблицу (`ControlStore.cs:81`): + +```sql +CREATE TABLE IF NOT EXISTS metric_samples ( + sequence INTEGER PRIMARY KEY AUTOINCREMENT, + node_id TEXT NOT NULL REFERENCES agents(node_id) ON DELETE CASCADE, + recorded_at TEXT NOT NULL, + payload_json TEXT NOT NULL +); +CREATE INDEX IF NOT EXISTS ix_metric_samples_node_time + ON metric_samples(node_id, recorded_at DESC); +``` + +Наполняется она из heartbeat агента, чистится по `MetricRetentionHours` +(по умолчанию 168 часов). При этом в группе `/api/v1/control` **нет ни +одного маршрута для метрик** — я перечитал все `control.Map*` в +`Program.cs`. То есть оператор физически не может их получить. + +## Что нужно сделать + +1. **Добавить в Control чтение метрик под ролью Operator.** Как минимум + последний срез по каждому узлу и история по одному узлу за period. + Форму запроса, имена полей и ограничение на объём выбираешь сам и + обосновываешь в отчёте. Обязательные требования: маршрут в группе + `control` (то есть `RequireAuthorization("Operator")`), ограничение + количества возвращаемых точек, и никакого доступа к чужим данным по + роли Agent или Automation. +2. **Показать это в консоли** в разделе узлов: текущие CPU, память, диск и + задержка рядом с узлом, плюс короткая история — так же, как её + показывает Windows-клиент. +3. **`payload_json` — данные из внешнего источника.** Он приходит от + агента. Разбирать его в консоли только через уже имеющийся + `escapeHtml`, как это сделано с payload событий; ни одной вставки в + `innerHTML` без экранирования. Отсутствующие или битые поля не должны + ронять таблицу узлов. + +## Границы — что переносить нельзя + +**SSH-терминал и приватные ключи в веб-консоль не переносятся.** Это не +вопрос трудоёмкости, а заявленное свойство продукта: README обещает +«opens direct SSH terminals without sending a private terminal key to the +Hub», а ключ мониторинга и сертификат оператора защищены DPAPI и лежат +только на Windows-машине. Страница Sessions остаётся у Windows-клиента. + +Также не входит в эту задачу и делается отдельно: страница Settings, +группы и теги серверов, alert rules и журнал уведомлений (последние два +пункта в `docs/roadmap.md` числятся невыполненными и для Windows-клиента). + +Не трогать: `deploy/**`, релизные workflow, Desktop, схему существующих +таблиц (добавление индексов допустимо и обосновывается). + +## Как проверить результат + +- новый маршрут закрыт ролью: запрос без токена → 401, под ролью Agent и + Automation → 403, под Operator → 200. Три теста, вывод в отчёт; +- ограничение объёма истории проверено тестом: запрос заведомо большего + количества точек возвращает не больше предела; +- битый или неполный `payload_json` не роняет ни маршрут, ни отрисовку — + тест на каждую сторону; +- `dotnet test` целиком зелёный, с выводом; +- прогоны CI на PR — ссылками. + +## Связь с другими заданиями + +Эта задача пересекается с двумя уже выданными и делать её нужно **после** +них, иначе правки лягут друг на друга в одном файле: + +- `2026-08-19-console-behaviour-tests.md` — поведенческие тесты консоли. + Новая функциональность обязана прийти с такими тестами сразу, а не + проверками строк в HTML; +- `2026-08-19-console-events-throttle.md` — троттлинг обновления дашборда. + Метрики увеличат объём каждого обновления, поэтому без троттлинга + усиление нагрузки станет заметнее. + +Если считаешь, что порядок должен быть другим, — скажи в отчёте и обоснуй, +это решение приму. + +## Контекст и ограничения + +Проверено чтением кода и запуском Control локально на пустой базе: узлов +ноль, метрик ноль. Как выглядят настоящие `payload_json` от живого агента, +я не видел — на живом Hub не проверял. Прежде чем фиксировать контракт +ответа, посмотри фактическую форму payload в коде агента, а не в моём +описании.