+```
+
+When `consider_term_frequency` is enabled on a string field, the field summary includes `+TF`:
+
+```
+... composite threshold 0.7: business_name (w=1.0+TF), address (w=0.8) ...
+```
+
+When `K = 1`, the verb is `is`; when `K > 1`, the verb is `are`.
+
+### What the numbers mean
+
+- **N:** the count of distinct records actually analyzed by entity resolution (after the filter, after the null filter on blocking fields, and after de-duplication on the resolution inputs).
+- **D:** the number of distinct entity clusters produced.
+- **T:** the composite match threshold the check is configured with.
+- **K:** the number of clusters where `countDistinct(distinction_field) > 1` (the non-compliant clusters).
+
+## Source Records: What You Will See in the Anomaly
+
+The Shape Anomaly's **Source Records** panel surfaces the rows that explain the violation. For Entity Resolution the rule is:
+
+1. Take only the non-compliant clusters (clusters where the distinction field has more than one distinct value).
+2. Within each non-compliant cluster, keep **one example row per distinct value of the distinction field**.
+
+A cluster where `business_id` takes three different values across its records will contribute three rows to the source records (one per `business_id`), not the full set of records in that cluster. This makes the conflicting values visible at a glance without flooding the panel with redundant duplicates of the same `business_id`.
+
+Every source record carries the `_qualytics_entity_id` column so the cluster boundaries are obvious: records sharing the same `_qualytics_entity_id` are the records the platform thinks describe the same entity.
+
+## Performance Considerations
+
+Entity resolution is more expensive than simple field-by-field checks because every candidate pair must be scored. Two practical implications:
+
+- **Use blocking (exact) target fields when possible.** A blocking field (such as `country_code` or `tenant_id`) prevents the platform from comparing every record against every other record; only records sharing the blocking value are even considered. This is the single most effective lever for reducing cost on large containers.
+- **Filter to a meaningful scope.** If uniqueness across an entire table is not needed (for example, you only want to resolve entities within the current tenant), set the filter to that scope explicitly.
+
+## Relationship with Other Rule Types
+
+Entity Resolution sits next to a few related rule types in the platform; combining them is common:
+
+| Rule Type
| Why pair it with Entity Resolution |
+|:---|:---|
+| [Unique](../unique/introduction.md){:target="_blank"} | Unique guarantees no two rows share a value (or tuple of values) on the selected field(s). Entity Resolution goes further: it tolerates spelling variations and proximity, then asserts that those variations describe the same logical entity. Use Unique on a strict identifier (a primary key) and Entity Resolution on the descriptive fields that *should* identify the entity if normalized. |
+| [Not Null](../not-null-check.md){:target="_blank"} | Records where a blocking (`exact`) target field is NULL cannot be paired, so blocking fields with many NULLs silently skip resolution. Pair Entity Resolution with a Not Null check on those fields to make the omission visible. |
+| [Satisfies Expression](../satisfies-expression-check.md){:target="_blank"} | Use Satisfies Expression to normalize a field before Entity Resolution runs (for example, lower-casing emails, stripping punctuation, or pre-computing a phonetic key). Pre-normalization reduces the work that fuzzy matching has to do. |
+
+## Related
+
+- [Introduction](introduction.md){:target="_blank"}: formal definition, target field types, field scope, and general/anomaly properties.
+- [Examples](examples.md){:target="_blank"}: three production scenarios with sample data, source records, and resulting anomalies.
+- [API](api.md){:target="_blank"}: payload shape and field notes for creating an Entity Resolution check programmatically.
+- [FAQ](faq.md){:target="_blank"}: short answers to the most frequent questions.
diff --git a/docs/data-quality-checks/entity-resolution/introduction.md b/docs/data-quality-checks/entity-resolution/introduction.md
new file mode 100644
index 0000000000..20beef43aa
--- /dev/null
+++ b/docs/data-quality-checks/entity-resolution/introduction.md
@@ -0,0 +1,94 @@
+# Entity Resolution
+
+## Definition
+
+*Asserts that records with similar values across the configured target fields are resolved as the same entity and share a single distinction-field value.*
+
+## Overview
+
+Entity Resolution is a multi-field rule. You pick one or more **target fields** that describe the entity (for example, `name`, `address`, `phone`), choose how each field is compared (fuzzy text, numeric proximity, datetime tolerance, or exact match), and the platform clusters records whose weighted similarity meets the **composite match threshold**. Each cluster is assigned a unique **entity identifier** (`_qualytics_entity_id`).
+
+Once clusters are built, the rule checks the **distinction field**: every record in the same cluster must share the same value of the distinction field. Clusters that hold more than one value of the distinction field are flagged.
+
+Typical use cases:
+
+- Match customer or company records with name and address variations.
+- Consolidate duplicate entities across systems that emit slightly different spellings.
+- Identify fuzzy matches for deduplication before promoting records downstream.
+
+## Field Scope
+
+**Calculated:** Entity Resolution does not take a fixed list of fields. Instead, the platform derives the evaluated fields from the **target fields** you configure (each entry names a single field plus a comparison strategy). The **distinction field** is configured separately.
+
+**Distinction Field: Accepted Types**
+
+| Type | Supported |
+|-------------|:--------------------------------------------------------------------------------------:|
+| `Date` | :material-check-circle:{ style="color: #4caf50" }
|
+| `Timestamp` | :material-check-circle:{ style="color: #4caf50" }
|
+| `Integral` | :material-check-circle:{ style="color: #4caf50" }
|
+| `Fractional`| :material-check-circle:{ style="color: #4caf50" }
|
+| `String` | :material-check-circle:{ style="color: #4caf50" }
|
+| `Boolean` | :material-check-circle:{ style="color: #4caf50" }
|
+
+**Target Field Types**
+
+| Target Field Type | Compared How |
+|:---|:---|
+| String | `fuzzy` (default): fuzzy text similarity, optionally promoted to a perfect match by substring containment or phonetic (homophone) match. Term-frequency weighting can also be enabled to reduce the impact of common tokens. `exact`: blocking pre-filter. |
+| Numeric | `absolute` (default): pair matches if the difference is within a fixed delta. `relative`: pair matches if the difference is within a percentage. `exact`: blocking pre-filter. |
+| Datetime | `offset` (default): pair matches if both timestamps are within a number of seconds. `granularity`: pair matches if both timestamps fall in the same `Day`, `Week`, `Month`, or `Year`. `exact`: blocking pre-filter. |
+
+## General Properties
+
+{%
+ include-markdown "components/general-props/index.md"
+ start=''
+ end=''
+%}
+
+## Anomaly Types
+
+{%
+ include-markdown "components/anomaly-support/index.md"
+ start=''
+ end=''
+%}
+
+## Next Steps
+
+
+
+- :material-information-outline:{ .lg .middle } **How It Works**
+
+ ---
+
+ Full semantics: clustering behavior, blocking vs. fuzzy fields, weighted composite score, threshold tuning, filter behavior, and how the anomaly is reported.
+
+ [:octicons-arrow-right-24: How It Works](how-it-works.md)
+
+- :material-clipboard-text-outline:{ .lg .middle } **Examples**
+
+ ---
+
+ Three production scenarios with sample data, source records, anomaly messages, and the clustering logic the platform applies.
+
+ [:octicons-arrow-right-24: Examples](examples.md)
+
+- :material-api:{ .lg .middle } **API**
+
+ ---
+
+ Payload shape and field notes for creating an Entity Resolution check programmatically.
+
+ [:octicons-arrow-right-24: API](api.md)
+
+- :material-help-circle-outline:{ .lg .middle } **FAQ**
+
+ ---
+
+ Short answers to questions about target fields, threshold tuning, source records, and anomaly reporting.
+
+ [:octicons-arrow-right-24: FAQ](faq.md)
+
+
diff --git a/docs/data-quality-checks/overview-of-a-check.md b/docs/data-quality-checks/overview-of-a-check.md
index faf8627146..e81450745f 100644
--- a/docs/data-quality-checks/overview-of-a-check.md
+++ b/docs/data-quality-checks/overview-of-a-check.md
@@ -168,7 +168,7 @@ For more details about check rule types, please refer to the [**Rule Types Overv
| [Contains Url](../data-quality-checks/contains-url.md) | Asserts that the values contain valid URLs. |
| [Data Diff](../data-quality-checks/data-diff-check.md) | Asserts that the dataset created by the targeted field(s) has differences compared to the referred field(s). |
| [Distinct Count](../data-quality-checks/distinct-count-check.md) | Asserts on the approximate count distinct of the given column. |
-| [Entity Resolution](../data-quality-checks/entity-resolution.md) | Asserts that every distinct entity is appropriately represented once and only once. |
+| [Entity Resolution](../data-quality-checks/entity-resolution/introduction.md) | Asserts that records with similar values across the configured target fields are resolved as the same entity and share a single distinction-field value. |
| [Equal To](../data-quality-checks/equal-to-check.md) | Asserts that all of the selected fields equal a value. |
| [Equal To Field](../data-quality-checks/equal-to-field-check.md) | Asserts that this field is equal to another field. |
| [Exists in](../data-quality-checks/exists-in-check.md) | Asserts if the rows of a compared table/field of a specific Datastore exists in the selected table/field.|
diff --git a/docs/data-quality-checks/rule-types-overview.md b/docs/data-quality-checks/rule-types-overview.md
index 7f08905007..9e9491abf2 100644
--- a/docs/data-quality-checks/rule-types-overview.md
+++ b/docs/data-quality-checks/rule-types-overview.md
@@ -20,7 +20,7 @@ Here’s an overview of the rule types and their purposes:
| [Contains Url](../data-quality-checks/contains-url.md) | Asserts that the values contain valid URLs. |
| [Data Diff](../data-quality-checks/data-diff-check.md) | Asserts that the dataset created by the targeted field(s) has differences compared to the referred field(s). |
| [Distinct Count](../data-quality-checks/distinct-count-check.md) | Asserts on the approximate count distinct of the given column. |
-| [Entity Resolution](../data-quality-checks/entity-resolution.md) | Asserts that every distinct entity is appropriately represented once and only once |
+| [Entity Resolution](../data-quality-checks/entity-resolution/introduction.md) | Asserts that records with similar values across the configured target fields are resolved as the same entity and share a single distinction-field value. |
| [Equal To Field](../data-quality-checks/equal-to-field-check.md) | Asserts that this field is equal to another field. |
| [Exists in](../data-quality-checks/exists-in-check.md) | Asserts if the rows of a compared table/field of a specific Datastore exists in the selected table/field.|
| [Expected Schema](../data-quality-checks/expected-schema-check.md) | Asserts that all selected fields are present and that all declared data types match expectations. |
diff --git a/docs/stylesheets/extra.css b/docs/stylesheets/extra.css
index acec27b991..83c7b8f776 100644
--- a/docs/stylesheets/extra.css
+++ b/docs/stylesheets/extra.css
@@ -955,6 +955,19 @@
color: var(--q-brick);
}
+/* Mirrors the source-records anomalous-cell treatment in the Qualytics app:
+ orange outline + warning-tinted background on cells whose value failed a check.
+ Use inside markdown table cells to mark a single value as anomalous. */
+.anomalous-cell {
+ display: inline-block;
+ padding: 0.05rem 0.4rem;
+ border: 1px solid var(--q-orange);
+ border-radius: 4px;
+ background-color: rgba(249, 103, 25, 0.12);
+ color: var(--q-brick);
+ font-weight: 500;
+}
+
.text-sm {
font-size: 0.7rem;
}
diff --git a/mkdocs.yml b/mkdocs.yml
index 649473ca96..96ddc93d73 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -314,7 +314,12 @@ nav:
- Contains Url: data-quality-checks/contains-url.md
- Data Diff: data-quality-checks/data-diff-check.md
- Distinct Count: data-quality-checks/distinct-count-check.md
- - Entity Resolution: data-quality-checks/entity-resolution.md
+ - Entity Resolution:
+ - Introduction: data-quality-checks/entity-resolution/introduction.md
+ - How It Works: data-quality-checks/entity-resolution/how-it-works.md
+ - Examples: data-quality-checks/entity-resolution/examples.md
+ - API: data-quality-checks/entity-resolution/api.md
+ - FAQ: data-quality-checks/entity-resolution/faq.md
- Equal to: data-quality-checks/equal-to-check.md
- Equal to Field: data-quality-checks/equal-to-field-check.md
- Exists In: data-quality-checks/exists-in-check.md
@@ -1162,7 +1167,8 @@ plugins:
'checks/contains-url.md': 'data-quality-checks/contains-url.md'
'checks/data-diff-check.md': 'data-quality-checks/data-diff-check.md'
'checks/distinct-count-check.md': 'data-quality-checks/distinct-count-check.md'
- 'checks/entity-resolution.md': 'data-quality-checks/entity-resolution.md'
+ 'checks/entity-resolution.md': 'data-quality-checks/entity-resolution/introduction.md'
+ 'data-quality-checks/entity-resolution.md': 'data-quality-checks/entity-resolution/introduction.md'
'checks/equal-to-check.md': 'data-quality-checks/equal-to-check.md'
'checks/equal-to-field-check.md': 'data-quality-checks/equal-to-field-check.md'
'checks/exists-in-check.md': 'data-quality-checks/exists-in-check.md'