Add or change a risk matrix
Risk policy in Atlas is data, not code. Adding a dimension, a factor, or a whole matrix is a YAML + reference-data change — no deployment required. Read Risk scoring first.
Matrix schema shape
A matrix schema has dimensions, each with factors; factors use a scoring method and are wired to an ontology field:
schema_id: "my_matrix_v1"
version: 1
name: "My AML Matrix"
dimensions:
jurisdiction_risk:
name: "Jurisdiction risk"
weight: 0.30
factors:
- id: "country_risk"
max_score: 100
scoring_method: "REFERENCE_LOOKUP" # or BOOLEAN, THRESHOLD_RANGES
scoring_config:
reference_dataset: "country_risk_list"
multi_value_strategy: "max"
wire_mapping:
ontology_field_path: "LegalEntity.jurisdiction"
aggregation:
method: "weighted_max" # weighted_average | weighted_max | highest_dimension
dimension_weights: { jurisdiction_risk: 0.30 }
risk_levels:
low: { min: 0, max: 39 }
medium: { min: 40, max: 69 }
high: { min: 70, max: 100 }
escalation_rules:
- id: "sanctioned_hit"
condition: { equals: true }
minimum_tier: "high"
# wired via wire_mappings["escalation.sanctioned_hit"]
Scoring methods
| Method | What it does |
|---|---|
REFERENCE_LOOKUP | Looks the entity value up in a frozen reference dataset (e.g. country-risk list, PEP tiers) |
BOOLEAN | Maps true/false/null to configured scores |
THRESHOLD_RANGES | Buckets a numeric value into score ranges |
Aggregation & escalation
- Aggregation combines dimension scores:
weighted_max(the EBA-style default: 0.6×max + 0.4×weighted-avg),weighted_average, orhighest_dimension. - Escalation rules are a one-way ratchet: if a condition fires and its
minimum_tieris higher than the computed score, the final score is raised — never lowered.
Reference datasets
REFERENCE_LOOKUP factors read frozen reference datasets from the
reference-data registry. To add one:
- Define a type (
data_shape:list,scored_table, orconfig) with column definitions. - Create a dataset version with the data, then activate it.
- Reference it from a factor's
scoring_config.reference_dataset.
The resolver is tenant-aware: a tenant's own dataset overrides the system default for the same
list_key. At publish time, the matrix freezes a snapshot of the exact dataset versions it
used, so evaluations stay deterministic even if the lists change later.
Publish, assign, evaluate
- Draft → published matrices are immutable once published; evaluations cite the version.
- Determinism & idempotency: the scorer hashes input, overrides, and output; an evaluation with an existing fingerprint returns the cached result instead of re-scoring.
- Batch evaluation re-scores a whole portfolio sequentially (a Temporal workflow), with a queryable progress state and a per-company failure list.
No code, mostly
Adding a dimension or matrix is purely YAML + reference data + publish — the scorer, mapper, and
persistence are generic. You only touch code if you need a new scoring method (add a function to
the SCORING_METHODS registry in src/risk_matrix/scorer.py). See
Risk scoring and
ADR-019.