Skip to content

Sentinel ​

Sentinel gives every incoming transfer an anomaly score from 0 (normal) to 1 (highly unusual). Depending on settings, the node then accepts it, flags it, refuses it, or — with the policy layer on — holds it for a while or until the owner confirms.

The model ​

A small network embedded in the node (8 inputs → 16 → 8 → 1, 289 parameters). Its inputs describe the transfer, not the person:

FeatureFrom
Size of the amount (log scale)value
Gas pricegas_price
Nonce gapnonce vs the last confirmed nonce
Recipient is newPrior transfers to the recipient
Round amountvalue
Sender velocityTransfers by the sender in the last 10 blocks
Share of balance movedvalue vs balance
Self-transferfrom == to

In consensus the node computes these from committed blocks only (velocity is counted from blocks, not from the mempool), so every validator gets the same score for the same transaction.

ScoreCategoryanomalous
< 0.5normalno
0.5 – 0.6suspiciousyes
0.6 – 0.8elevatedyes
≥ 0.8high_riskyes

Try it without sending anything:

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}

What happens to a transfer ​

Sentinel decision flow: a score at or above 0.85 is refused at ingress; otherwise, with the policy layer off the transfer applies (flagged if anomalous); with it on, a trusted recipient applies normally, a score at or above 0.70 (or 0.60 for a session key) is held until the owner confirms, a score from 0.60 is held and released automatically after 50 blocks

Always on live ​

  • sentinel_enabled = 1: every transfer is scored when it reaches a node.
  • Score ≥ sentinel_reject_threshold (0.85) → refused with HTTP 400.
  • Anomalous but below that → accepted; the response carries sentinel_score, sentinel_category and sentinel_warning, and the gateway broadcasts tx_anomaly.

Policy layer off by default ​

With sentinel_policy_enabled = 1, a transfer that would otherwise apply can be held: the sender is debited, the recipient is not credited yet.

BandConditionWhat happens
TrustedRecipient is on the sender's active trust listApplied normally
HoldScore ≥ sentinel_hold_threshold (0.60)Released automatically after sentinel_hold_blocks (50); the sender may cancel before that
Step-upScore ≥ sentinel_stepup_threshold (0.70), or signed by a session key with score ≥ sentinel_agent_confirm_threshold (0.60)Waits for the owner to confirm with the master key; refunded if not confirmed within sentinel_confirm_expiry_blocks (1 000)

Held transfers have status held; they end as confirmed (released), cancelled or refunded. On cancel or refund the value returns to the sender; the fee is kept.

ActionEndpoint
List held transfersGET /api/v1/held/:address
Confirm (owner, master key)POST /api/v1/transactions/:hash/confirm
Cancel (owner)POST /api/v1/transactions/:hash/cancel

WebSocket events: tx_held, tx_released, tx_cancelled.

Trust list ​

An owner can mark recipients as trusted; transfers to them skip the hold. A new entry becomes active only after trust_activation_blocks (300) — so a stolen key cannot add an attacker's address and use it at once.

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

Session keys can't approve themselves ​

Anything aimed at neuro:system.trust — trust-list changes, confirming or cancelling a held transfer — is refused for session keys. An AI agent can start a risky transfer; only the owner's master key can let it through. See Account abstraction.

Calibration experimental ​

The model is trained on synthetic transaction patterns. Real transfers score higher than the synthetic data suggested: on a test network a plain 1.5 NRO transfer to a new recipient scores about 0.62, and measured scores rarely exceed about 0.74. Two consequences:

  • The 0.85 reject threshold is effectively never reached.
  • With the default thresholds, turning the policy layer on would hold many ordinary transfers to new recipients.

Thresholds are governance parameters and will be tuned, and the model retrained, on real transaction data before the policy layer is enabled on a public network.

How it is tested: the policy layer passed a seven-step test on four validators with a quorum of three — automatic release, step-up confirmation through a different node, refund at expiry, cancellation through a third node, surviving a node restart, trust-list activation, and identical counters and state roots on every node. Node unit tests cover each branch.

Metrics ​

Prometheus counters, kept in chain state so every node reports the same numbers: nc_sentinel_flagged_total{category}, nc_sentinel_held_total, nc_sentinel_released_total{how}.