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

# decisionTable

> First-match priority routing on a fixed column set. Two- to three-dimensional lookups in tabular form.

A `decisionTable` is the workflow equivalent of a DMN-style lookup table. Columns are typed as `condition` (input) or `output`. Rows are evaluated top-down; the first row whose condition cells all match wins. The row's output cells are written to the context.

## Configuration

```jsonc theme={null}
{
  "id": "dt-kyc-outcome",
  "type": "decisionTable",
  "data": {
    "label": "KYC Outcome Router",
    "hitPolicy": "first",
    "description": "First-match priority. Drives downstream provisioning or reject.",
    "columns": [
      { "id": "c-band",   "field": "ai_risk_synthesis.risk_band",       "operator": "==", "type": "condition" },
      { "id": "c-rec",    "field": "ai_risk_synthesis.recommendation",  "operator": "==", "type": "condition" },
      { "id": "c-out",    "field": "kyc_outcome",                       "operator": "==", "type": "output"    },
      { "id": "c-reason", "field": "kyc_outcome_reason",                "operator": "==", "type": "output"    }
    ],
    "rows": [
      { "id": "r1", "values": { "c-band": "LOW",      "c-rec": "APPROVE", "c-out": "provision_account", "c-reason": "Clean — auto-provision" } },
      { "id": "r2", "values": { "c-band": "MEDIUM",   "c-rec": "APPROVE", "c-out": "provision_account", "c-reason": "Borderline-clean — client may request additional review" } },
      { "id": "r3", "values": { "c-band": "HIGH",     "c-rec": "*",       "c-out": "officer_review",    "c-reason": "Elevated risk — compliance officer review" } },
      { "id": "r4", "values": { "c-band": "CRITICAL", "c-rec": "*",       "c-out": "reject",            "c-reason": "Sanctions / hard fraud — reject" } }
    ]
  }
}
```

## Columns

| `type`      | Purpose                                                                                                                                                |
| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `condition` | A value to match against the run context. `field` is the variable path; `operator` is the comparison; row cell is the literal value (or `*` wildcard). |
| `output`    | A value to write back. `field` is the destination variable; row cell is the value.                                                                     |

## Hit policy

| Policy     | Behaviour                                                            |
| ---------- | -------------------------------------------------------------------- |
| `first`    | First matching row wins. Default and most-used.                      |
| `priority` | Same as `first` but rows are ordered by an explicit priority column. |
| `unique`   | Exactly one row must match. Two matches = error.                     |
| `any`      | All matching rows must have identical outputs; otherwise error.      |
| `collect`  | All matching rows' outputs accumulate into arrays. Rare.             |

## Wildcard

A cell value of `*` matches anything in that column. Use it to express defaults that depend on the *other* condition columns.

## Routing

Each output's `field` ends up on the run context, and downstream split nodes route on it:

```mermaid theme={null}
flowchart LR
  DT[Decision Table<br/>KYC Outcome Router] --> S{kyc_outcome}
  S -- provision_account --> Provision[Provisioning]
  S -- officer_review    --> Officer[Officer Review]
  S -- reject            --> Reject[REJECT terminal]
```

## decisionTable vs rule

Prefer `decisionTable` when:

* the input is two or more orthogonal variables (band × recommendation, event × status, …);
* the table reads cleanly as a row-per-policy declaration;
* compliance is going to maintain it (analysts read tables faster than nested boolean clauses).

Prefer `rule` when:

* the gate is one variable with branching else clauses;
* conditions need composite logic (`(A AND B) OR (C AND NOT D)`).
