Entity Matching
Every promote operation has to decide, for each source entity, whether a corresponding destination entity already exists or whether a new one must be created. This decision is what entity matching does. It is the mechanism that makes re-promotion safe: instead of creating duplicates, the platform finds the destination entity that was produced by a previous promotion and updates it in place.
This page explains the two-phase matching strategy the platform uses, what each phase considers, and how the matching outcome maps to the per-entity result (created, updated, skipped, or failed).
How Promote Decides What to Match
When you promote an entity (quality check, computed field, computed table, or computed file) from a source to a destination, the platform asks: is there already a destination entity that corresponds to this source? Two pieces of information drive the answer:
- Records of previous promotions. Every successful promotion (
createdorupdated) writes a promote result row that links the source entity ID to the destination entity ID, scoped to the destination container or datastore. These records are the first thing the platform checks. - Semantic match on the destination. If no previous promotion is found, the platform falls back to looking at the destination directly — by name for most types, or by attribute overlap for quality checks.
This two-step approach means a re-promotion always finds the destination it produced before — even after edits or renames — while a first-time promotion can still detect and reuse a destination entity that was authored manually.
Scope Keying Is Asymmetric
The destination scope used to look up a previous promotion differs by promote type:
| Promote Type | Destination Scope | Where the Scope Comes From |
|---|---|---|
| Quality Checks | destination_container_id |
Read from the operation parameters |
| Computed Fields | destination_container_id |
Read from the operation parameters |
| Computed Tables | destination_datastore_id |
Stored as a column on the operation |
| Computed Files | destination_datastore_id |
Stored as a column on the operation |
Container-scoped matching means a quality check promoted to two different containers in the same datastore creates two independent promote result records — one per destination container. Datastore-scoped matching means a computed table promoted to a datastore has a single record regardless of which container name it ends up in.
Only Successful Results Drive the Lookup
The Phase 1 lookup considers only created and updated results. skipped and failed results are not consulted. When the platform finds multiple successful results for the same source entity and destination scope, it uses the most recent one (highest result row ID).
Two-Phase Matching
The platform applies the same two-phase strategy across all promote types.
Phase 1: Match by Previous Promotion
The platform queries the promote result table for a previous successful promotion of the same source entity to the same destination scope. If a row exists, the recorded destination entity is reused — regardless of whether names have changed or the source has been edited since.
flowchart TD
Start([Source Entity]) --> Lookup{Previous promotion<br/>exists?}
Lookup -- Yes --> Found([Use recorded destination entity])
Lookup -- No --> Phase2([Proceed to Phase 2])
style Start fill:#4CAF50,color:#fff,stroke:#388E3C
style Found fill:#2196F3,color:#fff,stroke:#1565C0
style Phase2 fill:#FFA726,color:#fff,stroke:#F57C00
Phase 2: Fallback Match
If no previous promotion is found, the platform uses a type-specific strategy to detect a corresponding destination entity that may have been authored manually:
| Promote Type | Fallback Strategy | Match Criteria |
|---|---|---|
| Quality Checks | Overlap match | Same rule type, field set, rule-specific properties, and filter (see below) |
| Computed Fields | Name match | Same computed field name on the destination container (live rows only) |
| Computed Tables | Name match | Same container name on the destination datastore (includes soft-deleted) |
| Computed Files | Name match | Same container name on the destination datastore (includes soft-deleted) |
Soft-Delete Behavior
For computed tables and computed files, the fallback name match looks across both live and soft-deleted destinations. If a soft-deleted destination container is found, the promotion reactivates it (status returns to active) and updates its definition rather than creating a new container.
For quality checks and computed fields, the fallback name match runs on live rows only. If the previous destination entity has been hard-deleted, the lookup falls through and a new entity is created.
Quality Check Overlap Rules
The overlap match for quality checks is precise. Two checks are considered the same if all of the following match:
- Rule type — exact match.
- Field set — the source and destination fields produce the same set when compared case-insensitively.
- Rule-specific properties — only the properties that are meaningful for the given rule type are compared. The platform uses an allow-list, which includes (depending on the rule type):
ref_datastore_id,ref_container_id,window_size,ref_expression,ref_filter,field_name,expression,interval_name,comparison,required_labels,diff_change_types, plus anis_element_contextflag and a coverage indicator (100% vs. less-than-100%). - Filter expression — case-sensitive and whitespace-sensitive equality. A
NULLfilter is treated as the empty string for the purpose of comparison.
Two checks differing only in description, tags, or other metadata are still considered the same under this rule. Overlap matching only ever finds existing destination checks; if no overlap match is found, a new check is created.
Matching and updating use different criteria
The overlap rule above only decides whether an existing destination check should be reused. Once that decision is made, the platform runs a separate definition comparison to decide between skipped and updated. That comparison includes additional fields — notably the check description and additional_metadata (excluding promote-internal keys) — so two checks may match under overlap but still trigger an updated result if their descriptions or metadata diverge. Tag changes alone never trigger an update.
Decision After Matching
Once a match is found (through either phase), the platform compares the source and destination definitions:
flowchart TD
Match{Match found?} -- No --> Create([Create new entity])
Match -- Yes --> Compare{Definitions identical?}
Compare -- Yes --> Skip([Skip — no changes needed])
Compare -- No --> Update([Update destination entity])
style Create fill:#4CAF50,color:#fff,stroke:#388E3C
style Skip fill:#9E9E9E,color:#fff,stroke:#616161
style Update fill:#2196F3,color:#fff,stroke:#1565C0
Why Phase 1 Matters
The Phase 2 fallback alone would be enough for first-time promotions, but it breaks down once the source or destination has been edited. Phase 1 exists so that the source-to-destination identity stays stable across edits, independently of name or matching attributes.
The kinds of edits this protects against differ by entity type:
- Computed tables, computed files, computed fields — Renaming the source between promotions. Without a record of a previous promotion, the next promotion would look for a destination with the source's new name and create a fresh entity. With one, the platform finds the previously linked destination and updates its name to match.
- Quality checks — Quality checks have no user-editable name. A record of a previous promotion instead protects against edits to the matching attributes: filter expression, field set, or rule-specific properties. Without one, changing the filter on a previously promoted check would cause the next promotion to overlap-match against nothing and create a duplicate. With one, the destination link is preserved through any source edit.
Cross-Promotion Consistency
When you promote the same source entity to multiple destinations, each destination scope is matched independently. Re-promoting updates each destination's previously-linked entity without interference.
Failed Promotion Recovery
If a promotion fails for an entity, the result is recorded as failed but does not participate in subsequent Phase 1 lookups. On the next promotion attempt, the previous failed result for the same source-destination pair is removed and the new attempt records its result. This means failed promotions can be retried cleanly without stale failed rows accumulating against a source entity.
Promote Metadata
In addition to recording promote results, promoted entities receive metadata on the destination row that records their origin. The exact keys depend on the promote type:
| Metadata Key | Description |
|---|---|
promoted_from_datastore |
The source datastore name and ID |
promoted_from_container |
The source container name and ID |
promote_operation_id |
The ID of the promote operation that created or updated this entity |
| Metadata Key | Description |
|---|---|
promoted_from_datastore |
The source datastore name and ID |
promoted_from_container |
The source container name and ID |
promoted_from_computed_field |
The source computed field name and ID |
promote_operation_id |
The ID of the promote operation that created or updated this entity |
| Metadata Key | Description |
|---|---|
from_source_datastore |
The source datastore name and ID |
from_source_container |
The source container name and ID |
from_quality_check_id |
The ID of the source quality check |
promote_operation_id |
The ID of the promote operation that created or updated this entity |
This metadata is stored as additional properties on the destination entity and can be queried through the API.