A link can be correct when created and wrong after a catalog change. Preserve its original decision and review migrations.
Entity links across catalog renames, merges and deletions
Version the referent
A linked mention should record catalog ID, catalog revision, mention source revision and decision policy. A display name is not a durable identifier: services are renamed and aliases are reused. When a record is retired, keep a controlled historical view for authorized audit, while preventing new mentions from linking to it by default. A deletion under retention policy may require retiring derived links entirely. Candidate selection must use the active catalog snapshot.
Treat merges as proposed migrations
Two service records may later be declared the same system. Do not rewrite historical mention IDs silently. Stage a migration with old and new IDs, reason, affected mention count and a sample of source contexts. A merge may hide a distinction that mattered at the time, such as canary versus production. Review high-impact relation edges before changing identity. Relation ledgers need the same referent boundary.
Handle splits and alias reuse
A product can split into two services while retaining the original nickname. Historical mentions may be unresolved without sufficient context. Mark them as ambiguous rather than assigning all to one child record. A later customer may adopt an alias previously used elsewhere; tenant scope and effective dates prevent wrongful cross-links. Recompute the search index only from source revisions that are still authorized.
Audit link stability
Report changed links, NIL rate, wrongful merge rate and reviewer effort per catalog release. Compare old and new decisions on a frozen mention set. Investigate any newly visible cross-tenant candidate. Keep the prior catalog snapshot for rollback within retention rules. The service-linking project makes migration review part of routine operations.
Implementation
def stage_entity_migration(link, migration_map, catalog_revision):
if link["catalog_revision"] == catalog_revision:
return {"state": "unchanged", "entity_id": link["entity_id"]}
target = migration_map.get(link["entity_id"])
if target is None:
return {"state": "review", "reason": "no-approved-migration"}
return {"state": "review", "from_id": link["entity_id"],
"to_id": target, "new_revision": catalog_revision}
old_link = {"entity_id": "svc-47", "catalog_revision": "catalog-r7"}
assert stage_entity_migration(old_link, {"svc-47": "svc-91"},
"catalog-r8")["state"] == "review"
Performance and operating cost
A migration-map lookup is O(1) average time per link; reviewing m affected mentions requires O(m) sampling or rewriting work. Keeping catalog snapshots uses storage, but it prevents a later rename from changing the meaning of an old audit without a trace. Focus review on merges and splits with downstream relations or customer impact.
Common Mistakes
- Using a mutable display name as the saved identity.
- Rewriting historical link IDs automatically after a catalog merge.
- Assigning an ambiguous old alias to one new child after a split.
- Keeping deleted source mentions in a derived search index.
Read next
- Entity linking: candidate generation and the NIL decision
- Project: link incident mentions to a versioned service catalog
- Project: build a reviewed entity-relation ledger from incident notes
- Coreference chains: track mentions without guessing identity
- Audit redacted text flows, retention and re-identification risk
Continue the workflow: Multi-step evidence chains: join identity, revision and access.
Continue the workflow: Project: link vendor names across scripts without false merges.
