# Sentinel

> Sentinel — оцінка аномалій транзакцій у NeuroChain — вбудована модель і її ознаки, категорії, поріг відхилення на вході та необов'язковий шар політик, що утримує переказ чи просить підтвердження замість відмови, зі списками довіри й правилами для сесійних ключів.

Source: https://docs.nro.world/uk/ai/sentinel

Sentinel дає кожному вхідному переказу **оцінку аномальності** від 0 (звичайний) до 1 (дуже незвичний). Залежно від налаштувань нода його приймає, позначає, відхиляє або — з увімкненим шаром політик — утримує на деякий час чи до підтвердження власником.

## Модель

Невелика мережа, вбудована в ноду (8 входів → 16 → 8 → 1, 289 параметрів). Її входи описують переказ, а не людину:

| Ознака | Звідки |
|--------|--------|
| Розмір суми (логарифмічна шкала) | `value` |
| Ціна газу | `gas_price` |
| Розрив nonce | `nonce` порівняно з останнім підтвердженим |
| Новий отримувач | Попередні перекази цьому отримувачу |
| Кругла сума | `value` |
| Швидкість відправника | Перекази відправника за останні 10 блоків |
| Частка балансу, що переміщується | `value` порівняно з балансом |
| Переказ самому собі | `from == to` |

У консенсусі нода обчислює їх **лише із зафіксованих блоків** (швидкість рахується за блоками, а не за мемпулом), тож кожен валідатор отримує однакову оцінку для однієї транзакції.

| Оцінка | Категорія | `anomalous` |
|--------|-----------|-------------|
| < 0,5 | `normal` | ні |
| 0,5 – 0,6 | `suspicious` | так |
| 0,6 – 0,8 | `elevated` | так |
| ≥ 0,8 | `high_risk` | так |

Спробуйте, нічого не надсилаючи:

```bash
curl -s -X POST "$GATEWAY/api/v1/sentinel/score" -H 'Content-Type: application/json' \
  -d '{"value":45000000,"gas_price":2,"nonce":3,"last_nonce":2,"balance":48000000,
       "tx_count_last_10":1,"recipient_tx_count":0,"is_self_transfer":false}'
# {"anomalous":true,"category":"elevated","score":0.7119}
```

## Що відбувається з переказом

![Схема рішень Sentinel: оцінка 0,85 і вище відхиляється на вході; інакше з вимкненим шаром політик переказ застосовується (позначений, якщо аномальний); з увімкненим довіреному отримувачу переказ застосовується звичайно, оцінка 0,70 і вище (або 0,60 для сесійного ключа) утримується до підтвердження власником, оцінка від 0,60 утримується і звільняється автоматично через 50 блоків](/diagrams/uk/sentinel-policy.svg)

### Завжди увімкнено <Badge type="tip" text="працює" />

- `sentinel_enabled = 1`: кожен переказ оцінюється, коли доходить до ноди.
- Оцінка ≥ `sentinel_reject_threshold` (0,85) → відхилення з HTTP 400.
- Аномальний, але нижче цього порогу → приймається; відповідь містить `sentinel_score`, `sentinel_category` і `sentinel_warning`, а gateway розсилає `tx_anomaly`.

### Шар політик <Badge type="warning" text="вимкнено за замовчуванням" />

З `sentinel_policy_enabled = 1` переказ, який інакше застосувався б, може бути **утриманий**: відправника списано, але отримувачу ще не зараховано.

| Смуга | Умова | Що відбувається |
|-------|-------|-----------------|
| Довірений | Отримувач в активному списку довіри відправника | Застосовується звичайно |
| Утримання | Оцінка ≥ `sentinel_hold_threshold` (0,60) | Звільняється автоматично через `sentinel_hold_blocks` (50); до того відправник може скасувати |
| Підтвердження | Оцінка ≥ `sentinel_stepup_threshold` (0,70) **або** підпис сесійним ключем з оцінкою ≥ `sentinel_agent_confirm_threshold` (0,60) | Чекає, доки власник **підтвердить майстер-ключем**; повертається, якщо не підтверджено за `sentinel_confirm_expiry_blocks` (1 000) |

Утримані перекази мають статус `held`; завершуються як `confirmed` (звільнено), `cancelled` або `refunded`. При скасуванні чи поверненні сума повертається відправнику; комісія лишається.

| Дія | Ендпоінт |
|-----|----------|
| Список утриманих переказів | `GET /api/v1/held/:address` |
| Підтвердити (власник, майстер-ключ) | `POST /api/v1/transactions/:hash/confirm` |
| Скасувати (власник) | `POST /api/v1/transactions/:hash/cancel` |

Події WebSocket: `tx_held`, `tx_released`, `tx_cancelled`.

### Список довіри

Власник може позначити отримувачів як довірених; перекази їм оминають утримання. Новий запис стає активним лише через `trust_activation_blocks` (300) — тож викрадений ключ не може додати адресу зловмисника й одразу нею скористатися.

`POST /api/v1/trust/add`, `POST /api/v1/trust/remove`, `GET /api/v1/trust/:owner`.

### Сесійні ключі не можуть схвалити самі себе

Усе, що спрямоване на `neuro:system.trust` — зміни списку довіри, підтвердження чи скасування утриманого переказу, — для сесійних ключів відхиляється. AI-агент може почати ризикований переказ; пропустити його може лише майстер-ключ власника. Див. [Абстракція акаунтів](./account-abstraction).

## Калібрування <Badge type="warning" text="експериментально" />

Модель навчена на синтетичних шаблонах транзакцій. Справжні перекази отримують вищі оцінки, ніж передбачали синтетичні дані: у тестовій мережі звичайний переказ 1,5 NRO новому отримувачу дає близько **0,62**, а виміряні оцінки рідко перевищують приблизно **0,74**. Два наслідки:

- Поріг відхилення 0,85 фактично ніколи не досягається.
- З порогами за замовчуванням увімкнення шару політик утримувало б багато звичайних переказів новим отримувачам.

Пороги — параметри управління; їх буде налаштовано, а модель — перенавчено на справжніх даних транзакцій, перш ніж шар політик увімкнуть у публічній мережі.

**Як це тестується:** шар політик пройшов тест із семи кроків на чотирьох валідаторах з кворумом три — автоматичне звільнення, підтвердження через іншу ноду, повернення після закінчення строку, скасування через третю ноду, переживання перезапуску ноди, активація списку довіри та однакові лічильники й корені стану на кожній ноді. Модульні тести ноди покривають кожну гілку.

## Метрики

Лічильники Prometheus, що зберігаються в стані мережі, тож кожна нода звітує однакові числа: `nc_sentinel_flagged_total{category}`, `nc_sentinel_held_total`, `nc_sentinel_released_total{how}`.
