> Source: https://builder.ema.ai/v2/agent-reference/rule-validation
> Title: Rule Validator Agent

# Rule Validator Agent

The Rule Validator Agent (`rule_validation`) checks documents and data against a set of business rules you define and emits a verdict for each rule — pass/fail for boolean rules, a constrained score for numerical rules — along with a plain-English rationale and the verbatim evidence the verdict rests on. Use it for compliance checks, document review, quality scoring, and any task where you need an auditable, rule-by-rule judgment rather than a single freeform answer.

The Rule Validator Agent belongs to the **Frequently Used** group in the agent library.

Three things define how this agent behaves:

-   **Per-rule output.** Every rule gets its own verdict, rationale, and evidence list. Downstream nodes and dashboards render the array directly.
-   **Boolean and numerical rules are both first-class.** A numerical rule emits an integer score drawn from a set you constrain.
-   **Typed inputs land in the user message, never in the Instructions.** Documents and named inputs are wrapped in document markers so the model reads each one as a discrete piece of evidence — they are never folded into the system prompt.

## Configuration

You configure the agent through `agent_config.type_config`. The required field is `rules`.

```json
{
  "id": "contract_review",
  "type": "boolean",
  "rules": [
    {
      "rule_id": "R1",
      "rule_text": "The contract is signed on the final page.",
      "type": "boolean"
    },
    {
      "rule_id": "R2",
      "rule_text": "Rate the completeness of the liability section from 0 to 5.",
      "type": "numerical",
      "numerical_rule_config": { "possible_scores": [0, 1, 2, 3, 4, 5] }
    }
  ]
}
```

Field

Required

Purpose

`rules`

Yes

The list of rules to evaluate. At least one is required.

`type`

No

Default rule type (`boolean` or `numerical`) when a rule omits its own. Defaults to `boolean`.

`id`

No

Ruleset identifier, surfaced in the prompt and in error messages.

`global_numerical_rule_config`

Conditional

A `{min_score, max_score, increment}` range that numerical rules fall back to when they don't declare their own scores.

`boolean_aggregation` / `numerical_aggregation`

No

How leaf verdicts roll up. Boolean: `all` · `any` · `majority`. Numerical: `sum` · `mean` · `weighted_mean`.

`generate_report`

No

When true, the agent renders an Excel validation report and uploads it. See [Excel report](#excel-report).

### Per-rule fields

Field

Required

Purpose

`rule_id`

Yes

Stable identifier the model echoes back in its output. Must be unique within the ruleset.

`rule_text`

Yes

The human-readable rule statement the model evaluates.

`type`

No

`boolean` or `numerical`; inherits the ruleset default when omitted.

`numerical_rule_config.possible_scores`

Conditional

The exact integer scores a numerical rule may emit. Required for numerical rules unless the ruleset supplies a `global_numerical_rule_config`.

`not_applicable_text`

No

An alternate rule the model evaluates when the primary rule doesn't apply to the supplied inputs.

`name`

No

Display label shown in the Excel report; not seen by the model.

A numerical rule must resolve to a non-empty score set — either through its own `possible_scores` or through the ruleset's `global_numerical_rule_config` (which materializes a range from `min_score` to `max_score` by `increment`). A node whose numerical rule has neither is rejected with a validation error.

### Aggregation modes

When you set `boolean_aggregation` or `numerical_aggregation` on the ruleset, the agent rolls the per-rule verdicts up into a single ruleset-level result alongside the flat `rules` array. Rules marked not-applicable are excluded from the boolean denominator; numerical rules with insufficient data are excluded from the numerical aggregate.

Rule type

Mode

Result

Boolean

`all` (default)

Passes only when every applicable rule passes.

`any`

Passes when at least one applicable rule passes.

`majority`

Passes when more than half of the applicable rules pass.

Numerical

`sum`

Adds the rule scores.

`mean` (default)

Averages the rule scores.

`weighted_mean`

Accepted today; behaves as `mean` until per-rule weights are wired.

`nested_rulesets` and `filter_criteria` are accepted in the configuration schema for forward compatibility, so operators can author them ahead of full support.

## Inputs

Rule Validation takes typed inputs. All fields are optional, but **at least one** must be provided — the agent has nothing to evaluate otherwise.

Input key

Shape

Purpose

`primary_docs`

Array of strings or `{file_name|name|title, content|text|markdown}`

The documents the rules are evaluated against.

`auxiliary_docs`

Same shape as `primary_docs`

Supporting context (e.g. policy references).

`text_input`

String or `{text: string}`

Free-text input.

`named_inputs`

Array of `{name, description?, value}`

Typed key/value entries the model cites by name. Complex values render as JSON.

`message`

String

Back-compatible free-text message.

Documents are wrapped in `<------- Start of Document: name ------->` markers in the user message so the model treats each as discrete evidence. When `named_inputs` is absent, any other top-level input key is auto-promoted into a named input so workflows can wire individual scalar fields without hand-assembling an array.

**Input example**

```json
{
  "primary_docs": [
    { "file_name": "MSA-Acme.pdf", "content": "Master Services Agreement..." }
  ],
  "named_inputs": [
    { "name": "contract_value", "value": 250000 }
  ]
}
```

## Output

The output is a JSON object with a `rules` array — one entry per configured rule, keyed by `rule_id`, in the same order as your `rules` list.

```json
{
  "rules": [
    {
      "rule_id": "R1",
      "data_sufficiency": true,
      "rationale": "The agreement carries a signature block initialed on page 14.",
      "boolean_output": true,
      "not_applicable": false,
      "evidences": [
        { "text": "Signed: J. Smith, page 14", "source_origin": "MSA-Acme.pdf", "source_page_number": 14 }
      ]
    },
    {
      "rule_id": "R2",
      "data_sufficiency": true,
      "rationale": "The liability section covers caps and carve-outs but omits indemnity.",
      "numerical_output": 3,
      "not_applicable": false,
      "evidences": [ ... ]
    }
  ]
}
```

Per-rule field

Meaning

`rule_id`

Echoes the configured rule's `rule_id`.

`data_sufficiency`

True when the inputs let the model decide confidently; false when information is missing (a best-effort verdict is still emitted).

`rationale`

Plain-English explanation. Required for every rule.

`boolean_output`

For boolean rules — true when the rule is satisfied.

`numerical_output`

For numerical rules — an integer drawn from the rule's allowed scores.

`not_applicable`

True when the rule's preconditions don't apply to the inputs.

`evidences`

Verbatim quotes or data points justifying the verdict, each with a `source_origin` (document filename or named-input name) and `source_page_number` (0 for non-document sources).

Each evidence whose `source_origin` matches a supplied document produces a cited source on the response (deduplicated by origin, text, and page). A best-effort repair pass re-anchors paraphrased snippets to verbatim document spans.

## Validation behavior

The agent validates the model's output and retries (within the output-retry budget) with a corrective prompt when it finds a recoverable problem — malformed JSON, a code-fenced response, a missing or duplicated `rule_id`, a missing `rationale`, a boolean rule missing `boolean_output`, or a numerical score outside the allowed set. The per-rule output is re-ordered to match your configured rule order before it's returned.

## Excel report

When `type_config.generate_report` is true and the service has blob storage configured, the agent renders an Excel (`.xlsx`) validation report — a title row, summary statistics, and a per-rule row with pass/fail and score cells — and uploads it. The report descriptor appears on the response as `validation_report` (file name, URI, MIME type, and a tenant-relative `reference_id`). The file is downloaded through a tenant-scoped endpoint:

```http
GET /rule-validation-reports/{reference_id}     # JWT-authenticated (user)
GET /internal/rule-validation-reports/{reference_id}   # internal
```

Tenant scoping is derived from the verified auth context, never from the path, so a report uploaded by one tenant is unreachable to another.

## Long-running execution

Rule validation is a read-only, potentially long-running type, so it can run on the asynchronous execution path (`POST /internal/execute-async`) — the agent returns a job handle and posts the result back when finished. See the [Agent Reference overview](/builder/v2/agent-reference#long-running-async-execution).

## What's next

-   [Agent Reference overview](/builder/v2/agent-reference) — how agents work, the catalog, the four builder groups, and the shared execution engine.
-   [Data Extractor Agent](/builder/v2/agent-reference/extraction) — turn unstructured text into schema-conforming JSON.
-   [Custom Agent](/builder/v2/agent-reference/custom) — build a general-purpose agentic agent with Tools and an output schema.
