LICENSE appears twice in presidio_evaluator/entity_mapping/definitions.py:
- line 166, as a canonical leaf under
EMPLOYMENT
- line 241, as an alias of
PROFESSIONAL_LICENSE under GOVERNMENT_ID
Nothing says which one wins. _build_alias_map writes both and the last write survives, so the alias wins and the leaf becomes unreachable by its own name.
What it looks like
h = EntityHierarchy()
h.canonicalize("LICENSE") # 'PROFESSIONAL_LICENSE'
h.to_branch("LICENSE") # 'EMPLOYMENT'
h.get_branch("LICENSE") # ['PII', 'GOVERNMENT_ID', 'PROFESSIONAL_LICENSE']
Three lookups for one label, two different answers about which branch it belongs to. to_branch disagrees with the other two because it checks canonical_to_branch on the raw name first, and LICENSE is in there as a canonical leaf, so it returns EMPLOYMENT and never gets to the alias.
Why it is worth fixing now
Until recently you could not really run into it, because add_alias raised on anything touching LICENSE. #192 fixed that guard, correctly. The side effect is that the duplicate is now reachable:
h.add_alias("LICENSE", "PROF_LIC") # raised before #192, succeeds now
h.canonicalize("PROF_LIC") # 'LICENSE' -> EMPLOYMENT
h.canonicalize("LICENSE") # 'PROFESSIONAL_LICENSE' -> GOVERNMENT_ID
You declare two labels synonyms and get two labels that resolve to different entities in different branches. A dataset annotated PROF_LIC and a model predicting LICENSE will not match at the exact level or the branch level, and nothing warns.
Scope
Only this one. I walked every node in the tree and compared the node against where its own name resolves — LICENSE is the single case where they disagree.
DEVICE_IDENTIFIER has a similar shape (its name resolves to DEVICE_ID, an alias on its own child) but both sides stay inside the DEVICE_IDENTIFIER branch, so no lookup contradicts another. It is fine as is.
Assuming that LICENSE is government-issued ID, drop the EMPLOYMENT leaf and let LICENSE resolve to PROFESSIONAL_LICENSE.
Found while reviewing #192.
LICENSEappears twice inpresidio_evaluator/entity_mapping/definitions.py:EMPLOYMENTPROFESSIONAL_LICENSEunderGOVERNMENT_IDNothing says which one wins.
_build_alias_mapwrites both and the last write survives, so the alias wins and the leaf becomes unreachable by its own name.What it looks like
Three lookups for one label, two different answers about which branch it belongs to.
to_branchdisagrees with the other two because it checkscanonical_to_branchon the raw name first, andLICENSEis in there as a canonical leaf, so it returnsEMPLOYMENTand never gets to the alias.Why it is worth fixing now
Until recently you could not really run into it, because
add_aliasraised on anything touchingLICENSE. #192 fixed that guard, correctly. The side effect is that the duplicate is now reachable:You declare two labels synonyms and get two labels that resolve to different entities in different branches. A dataset annotated
PROF_LICand a model predictingLICENSEwill not match at the exact level or the branch level, and nothing warns.Scope
Only this one. I walked every node in the tree and compared the node against where its own name resolves —
LICENSEis the single case where they disagree.DEVICE_IDENTIFIERhas a similar shape (its name resolves toDEVICE_ID, an alias on its own child) but both sides stay inside theDEVICE_IDENTIFIERbranch, so no lookup contradicts another. It is fine as is.Assuming that LICENSE is government-issued ID, drop the
EMPLOYMENTleaf and letLICENSEresolve toPROFESSIONAL_LICENSE.Found while reviewing #192.