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

# Rule Engine

> How rules are evaluated inside Specter.

The rule engine evaluates the rules in your **active ruleset** against the decision context and produces the
outcome. Rules run in the **order they appear** in the ruleset; a `BLOCK` short-circuits evaluation, while
`REVIEW` outcomes accumulate. If no rule matches, the decision is `ALLOW`.

## Rule types

| Type            | Purpose                                                                                                  |
| --------------- | -------------------------------------------------------------------------------------------------------- |
| `condition`     | Match the decision context with a boolean expression and apply an action.                                |
| `backend`       | Delegate the decision to a [backend](/products/specter/concepts/backends) exposed by a Link integration. |
| `backend_group` | Evaluate several backends together as one rule.                                                          |
| `blacklist`     | Block when a context value matches a [blacklist](/products/specter/concepts/blacklist) entry.            |

Each rule carries an `action` (`ALLOW`, `REVIEW`, or `BLOCK`) and an `enabled` flag. Rules are evaluated in the
order they appear in the ruleset's `rules` array.

<Info>
  The exact ruleset JSON schema is documented in the [API
  reference](/products/specter/api-reference/rulesets/create-ruleset). This page
  describes the concepts; the schema is the source of truth for field names.
</Info>

## Conditions

A condition rule evaluates a boolean **expression tree** over the decision context, addressed with JSONPath
(`$.transaction.amount`, `$.metadata.channel`, …). Expressions compose:

* **Comparison** — `eq`, `neq`, `lt`, `lte`, `gt`, `gte`
* **Set membership** — value `in` a list
* **Boolean composition** — `and`, `or`, `not`
* **Velocity** — a rolling-window count (see below)

```text theme={null}
and(
  gte($.transaction.amount, 50000),
  eq($.credential.pan.scheme, "visa")
) → action: REVIEW
```

<Warning>
  Only paths that exist in the decision context resolve. An absent path — a typo, or an attribute the context
  does not carry — evaluates to `false` rather than raising an error, so a rule built on one is accepted and
  stays `ACTIVE` but never fires. Check your paths against the [decision
  request](/products/specter/api-reference/decisions/evaluate-transaction) before activating a ruleset.
</Warning>

## Velocity

Velocity conditions count how many decisions matched a given identity within a rolling time window — for
example, "more than 5 attempts on this card in the last hour". Counters are maintained atomically and
**fail open**: if the counter store is unavailable, the velocity check never blocks a transaction.

The following fields can be counted:

| Field                      | Counter                |
| -------------------------- | ---------------------- |
| `$.credential_fingerprint` | Per card instrument    |
| `$.device.ip`              | Per device IP          |
| `$.device.fingerprint`     | Per device fingerprint |
| `$.customer.id`            | Per customer           |

## Backend rules

A backend rule delegates the decision to a [backend](/products/specter/concepts/backends) exposed by a Link
integration. The rule names the integration `slug` and the `backend_id` to invoke; Specter calls Link to assess
the transaction and maps the outcome to a Specter decision.

Before any call, Specter checks that the context contains the backend's required fields. If any are missing, it
skips the backend with an `insufficient_context` result and makes no call.

Each backend rule has an `on_error` setting that governs what happens when the backend errors or times out:

| `on_error` | Behavior                                                           |
| ---------- | ------------------------------------------------------------------ |
| `allow`    | Skip the backend and continue evaluation (fail open). The default. |
| `block`    | Treat the failure as a `BLOCK`.                                    |
| `review`   | Treat the failure as a `REVIEW`.                                   |

## Evaluation order

```mermaid theme={null}
flowchart TB
    A[Evaluate enabled rules in array order] --> B{Evaluate next rule}
    B -->|Matches BLOCK| C[Return BLOCK]
    B -->|Matches REVIEW| D[Accumulate REVIEW]
    B -->|No match / ALLOW| E{More rules?}
    D --> E
    E -->|Yes| B
    E -->|No| F{Any REVIEW?}
    F -->|Yes| G[Return REVIEW]
    F -->|No| H[Return ALLOW]
```

## Related

<CardGroup cols={2}>
  <Card title="Rulesets" icon="layer-group" href="/products/specter/concepts/rulesets">
    Version and activate collections of rules.
  </Card>

  <Card title="Backends & connections" icon="plug" href="/products/specter/concepts/backends">
    Connect external risk engines.
  </Card>
</CardGroup>
