> ## Documentation Index
> Fetch the complete documentation index at: https://docs.didit.me/llms.txt
> Use this file to discover all available pages before exploring further.

# イベントルール - ベロシティ・比率・シーケンス・相関

> Diditでは、イベントデータに対してベロシティ、比率、順序付きシーケンス、複数の対象をまたぐ相関のルールを設定できます。取引ルールと同じルールビルダーで作成します。

[イベント](https://docs.didit.me/ja/transaction-monitoring/events.md)は取引と同じエンジンで評価されます。ルールモデル、条件で使用する語彙、アクションのセットはそれぞれ1つだけで、ルールはどのレコード種別に適用されるかを宣言するだけです。

## 適用先

`scope.record_types`によって、ルールが何に対して発火するかが決まります。

| `record_types` | 発火対象 |
| - | - |
| 省略、または`["transaction"]` | 取引のみ（**デフォルト**） |
| `["event"]` | イベントのみ |
| `["transaction", "event"]` | 両方 |

> [!NOTE]
>
> 省略した場合、ルールは取引のみを対象とします。イベント機能より前に作成されたルールはすべてこれまでとまったく同じように動作します。スコープがたまたま空だったという理由で、ルールがログインにマッチし始めることはありません。

コンソールでは、ルールのトリガーステップにある**適用先**セレクターがこれに当たります。イベントを選ぶと**イベントカテゴリ**のチェックリストが表示され、ルールをさらに絞り込めます。すべてのカテゴリを評価する場合は、何もチェックしないでください。

```json theme={null}
{
  "title": "Failed login burst",
  "scope": {
    "record_types": ["event"],
    "event_categories": ["security"]
  },
  "aggregation": [
    {
      "metric": "count",
      "operator": "gte",
      "value": 3,
      "window": "30m",
      "filters": {
        "subject_vendor_data": "__current__",
        "event.action_type": "login_failed"
      }
    }
  ],
  "actions": [
    { "type": "add_score", "value": 40 },
    { "type": "change_status", "value": "IN_REVIEW" }
  ]
}
```

`"__current__"`は「評価対象のイベントと同じ値」を意味します。これにより、ルールは特定の値を指定せずに*対象者ごと*、*デバイスごと*、*ラウンドごと*の条件を表現できます。

## イベントフィールド

条件は名前空間付きのパスを読み取ります。すでにおなじみの取引の語彙（`action_type`、`subject_vendor_data`、`subject_ip_country`、`custom_values.<key>`）は、イベントでも参照できます。

| グループ | パス |
| - | - |
| イベント | `event.category`, `event.action_type`, `event.occurred_at`, `event.amount`, `event.currency`, `event.direction`, `event.session_id`, `event.session_sequence`, `event.score`, `event.status`, `event.ingest_source`, `event.retention_class`, `event.subject_vendor_data`, `event.business_vendor_data` |
| デバイスとネットワーク | `event.device.fingerprint`, `event.device.persistent_device_id`, `event.device.bot_score`, `event.ip.address`, `event.ip.country`, `event.ip.asn_number`, `event.ip.asn_organization`, `event.ip.is_vpn_or_tor`, `event.ip.is_data_center`, `event.ip.proxy_type`, `event.ip.country_name`, `event.ip.city`, `event.ip.connection_type`, `event.ip.travel_distance_km`, `event.ip.travel_speed_kmh` |
| ゲームプレイ | `event.gameplay.game_id`, `event.gameplay.table_id`, `event.gameplay.round_id`, `event.gameplay.hand_id`, `event.gameplay.match_id`, `event.gameplay.market_id`, `event.gameplay.side`, `event.gameplay.role`, `event.gameplay.counterparty_vendor_data`, `event.gameplay.net_result_amount`, `event.bonus.bonus_id`, `event.affiliate.affiliate_code` |
| 決済と紛争 | `event.payment.reference_id`, `event.payment.payment_fingerprint`, `event.payment.instrument_reference_hash`, `event.payment.withdrawal_address_hash`, `event.dispute.dispute_id`, `event.dispute.chargeback_id` |
| セキュリティと責任あるギャンブル | `event.security.changed_field`, `event.responsible_gambling.identity_match_ref` |
| ボットとアシストのテレメトリ | `event.bot.timing_variance_ms`, `event.bot.actions_per_minute`, `event.bot.pointer_entropy`, `event.bot.reaction_time_ms_p50`, `event.bot.assistance_indicator` |
| 対象者シグナル | `subject.email.risk_score`, `subject.email.social_count`, `subject.email.is_disposable`, `subject.email.deliverability`, `subject.email.domain_reputation`, `subject.email.first_seen_days`, `subject.email.is_breached`, `subject.phone.risk_score`, `subject.phone.line_type`, `subject.phone.social_count`, `subject.phone.carrier`, `subject.phone.country`, `subject.phone.is_disposable` |
| その他 | `event.payload.<key>`, `custom_values.<key>` |

対象者シグナルはイベントごとに再計算されるのではなく、モニタリング対象のユーザーに対してキャッシュされます。そのため、ルールは取り込み時にこれらを読み取れます。

## 集計

### ベロシティ

取引ですでに使っているリデューサー（`count`、`sum`、`avg`、`min`、`max`、`distinct_count`）を、ローリング`window`（`30m`、`24h`、`7d`、`30d`）にわたって適用します。

### 比率

同じウィンドウにわたる2つのリデューサーです。賭け額対入金額、出金額対入金額、ボーナス対入金額、チャージバック率はこの方法で表現します。

```json theme={null}
{
  "metric": "ratio",
  "window": "24h",
  "filters": { "subject_vendor_data": "__current__" },
  "numerator":   { "metric": "sum", "field": "event.amount", "filters": { "event.action_type": "bet_placed" } },
  "denominator": { "metric": "sum", "field": "event.amount", "filters": { "event.action_type": "deposit_completed" } },
  "operator": "lte",
  "value": 0.1
}
```

1,000を入金し、20を賭けて出金を申請すると、比率は0.02になります。最小限のプレイによる典型的なマネーロンダリングです。

> [!NOTE]
>
> **分母のない比率は決して一致しません**。入金がないことは比率ゼロではなく、根拠がないということです。ここで発火させると、新規ユーザー全員にフラグが立ってしまいます。

### シーケンス

ウィンドウ内の順序付き述語です。各ステップは`action_type`、`event_category`、または任意の`match`フィルターで一致を判定し、シーケンスが次に進む前に`min_count`回の発生を要求できます。

```json theme={null}
{
  "metric": "sequence",
  "key": "ato_drain",
  "window": "24h",
  "steps": [
    { "event_category": "security", "action_type": "login_failed", "min_count": 3 },
    { "event_category": "security", "action_type": "mfa_changed" },
    { "event_category": "payment",  "action_type": "withdrawal_address_changed" },
    { "event_category": "payment",  "action_type": "withdrawal_requested" }
  ]
}
```

クレデンシャルスタッフィング、次にMFAの乗っ取り、次に支払先の変更、そして資金の引き出し。ルールはチェーンを完了させたイベントで発火し、一致した根拠には各ステップのイベントIDが列挙されます。

シーケンスの状態はルールと対象者ごとに保持されるため、タイムラインを再スキャンすることなく、イベントの到着に応じて進行します。ウィンドウより古い進行状況はカウントされず、破棄されます。

### 相関

対象者をまたぐ結合です。このイベントと同じグループを共有するすべてのイベントにわたって集計します。

```json theme={null}
{
  "metric": "correlation",
  "window": "7d",
  "pair": true,
  "group_by": ["subject_vendor_data", "event.gameplay.counterparty_vendor_data"],
  "filters": { "event.action_type": "p2p_settlement" },
  "correlate": {
    "metric": "sum",
    "field": "event.gameplay.net_result_amount",
    "filters": { "event.gameplay.role": "winner" }
  },
  "operator": "gte",
  "value": 500
}
```

`"pair": true`は両端を順序のない集合として照合するため、A→BとB→Aは同じグループに入ります。これにより、1つのルールで共謀の両側を把握できます。チップダンピング、反対ベッティング、アフィリエイトによる自己リファラルは、いずれもこの形です。

相関ルールには必ず絞り込み用の`filters`を指定してください。指定しないと、ウィンドウ内のすべてのイベントが対象になります。

## リアルタイムルールと非同期ルール

取り込みリクエスト内で結果を返せるルールと、できないルールがあります。

| 実行タイミング | 対象ルール |
| - | - |
| **リクエスト内** | ベロシティ、比率、範囲が限定されたシーケンス（ウィンドウは最大24時間） |
| **数分以内に非同期で** | 相関ルール、およびウィンドウが24時間を超えるシーケンス |

ルールが保留中のイベントは、`"correlation_pending": true`付きで返されます。非同期処理が完了すると、既存のイベントのステータスとスコアが更新されます。再実行は冪等なため、ルールがスコアを二重に適用することはありません。

この分担は意図的なものです。複数の対象者にまたがるリングのクエリのために、ログインを待たせてはならないからです。

## アクション

取引ルールと同じアクション（`add_score`、`change_status`、`add_tags`、`add_note`、`add_to_list`、`open_case`）を使用します。

イベントでは次の2点が異なります。

* `AWAITING_USER`への`change_status`は取引専用の結果であるため（イベントには是正フローがありません）、`IN_REVIEW`として適用されます。
* `open_case`は、ケースを取引ではなく**対象者**に紐付け、一致したイベントIDをケースに記録します。

## エビデンス

すべての一致には、集計ウィンドウ、算出値、期待値、サンプリングされたイベントID、**一致した各フィールドのソース**が保存されます。

| ソース | 意味 |
| - | - |
| `server` | Diditが導出した値です（IP、ユーザーエージェント、オリジン）。信頼できる値です。 |
| `sdk` | Didit SDKがデバイスから報告した値です。 |
| `customer` | お客様のシステムが提供した値です。 |

そのため、アナリストは一致に対してアクションを起こす前に、サーバーで記録されたIPとクライアントが提供したヒントを区別できます。コンソールでは、イベントドロワー内の一致した各フィールドの横にソースが表示されます。

## 実例

> [accordion] 最小限のプレイによるマネーロンダリング
>
> 入金し、形だけのプレイを行い、すぐに出金するパターンです。条件`event.action_type eq withdrawal_requested`に加え、前述の賭け金対入金比率を`24h`の期間で`lte 0.1`に設定します。

> [accordion] フレンドリー詐欺
>
> 対象者ごとの`count(chargeback_opened)`と`count(deposit_completed)`の比率を`30d`の期間で`gte 0.5`に設定します。対象者の代わりに`event.payment.payment_fingerprint`でグループ化すると、複数のアカウントにまたがって使われる1つの決済手段を検出できます。

> [accordion] アカウント乗っ取りによる資金流出
>
> 前述の`ato_drain`シーケンスに、`add_score 90`と`change_status DECLINED`を組み合わせます。

> [accordion] チップダンピング
>
> 前述のペア相関を使用します。`value`をお客様のテーブルにとって重要な金額まで引き上げ、`group_by`に`event.gameplay.game_id`を追加してゲームごとに分けて集計します。

> [accordion] ボットによるプレイとリアルタイムアシスト
>
> `event.action_type eq bot_signal_observed`、`event.bot.timing_variance_ms lte 10`、`event.device.bot_score gte 90`を条件とし、`add_tags`を設定します。IPごとの`event.device.fingerprint`の`distinct_count`と組み合わせると、単一のスクリプトではなくファーム全体を検出できます。

> [accordion] 自己排除の回避
>
> `event.action_type eq self_exclusion_match`と`event.payload.re_registration_attempt eq true`を条件とし、`open_case`でエスカレーションします。

## 次のステップ

> [card] [イベントの取り込み](https://docs.didit.me/ja/transaction-monitoring/events.md)
>
> エンベロープ、10のカテゴリ、バッチの仕様について説明します。

> [card] [ルールAPI](https://docs.didit.me/ja/transaction-monitoring/rules-api.md)
>
> プログラムでルールを作成、更新、バックテストできます。


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.