fix(detection): preserve source spelling in augmented and split-name spans
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 82/100
Research direction
Read engine/detection/postprocess.py, focusing on apply_augmented_entities() and _split_full_names(), where the issue identifies the two span construction sites. Start by comparing their value handling with expand_entity_occurrences(), which already preserves source slices. Add regression coverage for the described case variants and name splits without inference; done means both source matches are replaced while matching rules, offsets, labels, provenance, and strict replacement checks remain unchanged.
Written by the indexing model from the issue text.
Description
Priority Level
Medium (has a local workaround)
Describe the bug
Augmented entities and split full-name parts use case-insensitive occurrence matching, but their EntitySpan.value retains the suggestion's spelling rather than the text at the matched offsets. The replacement primitive correctly requires exact agreement between the source slice and entity value, so it skips matches whose capitalization differs.
Steps/Code to reproduce bug
This example uses invented names and no model calls:
import pandas as pd
from anonymizer.config.replace_strategies import Redact
from anonymizer.engine.constants import (
COL_FINAL_ENTITIES,
COL_REPLACED_TEXT,
COL_REPLACEMENT_APPLICATION,
COL_TEXT,
)
from anonymizer.engine.detection.postprocess import apply_augmented_entities
from anonymizer.engine.replace.strategies import apply_local_replace_strategy
text = "Alice met ALICE."
entities = apply_augmented_entities(
text=text,
entities=[],
augmented_output={"entities": [{"value": "Alice", "label": "first_name"}]},
)
result = apply_local_replace_strategy(
pd.DataFrame({
COL_TEXT: [text],
COL_FINAL_ENTITIES: [{"entities": [entity.as_dict() for entity in entities]}],
}),
strategy=Redact(),
)
print(result[COL_REPLACED_TEXT].iloc[0])
print(result[COL_REPLACEMENT_APPLICATION].iloc[0])
Current output is [REDACTED_FIRST_NAME] met ALICE. with one applied span and one skipped span. _split_full_names() has the same problem for standalone variants such as JOHN after a John Smith full-name detection.
Expected behavior
Each matched entity should use text[start:end] as its value, preserving the exact source spelling. Both matches should be replaced. Matching rules, offsets, labels, provenance, and strict replacement checks should stay the same.
Additional context
Observed on main at 1872309. The detector parser and expand_entity_occurrences() already preserve source slices. The proposed correction applies the same rule to the two remaining construction sites in engine/detection/postprocess.py. Regression coverage can exercise case variants, Unicode spelling, and first/middle/last-name splits without inference.
- Dominant language
- Python
- Stars
- 136
- Forks
- 22
- Avg merge
- 1d 22h
- Merged PRs (30d)
- 47
Getting set up
- No Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from NVIDIA-NeMo/Anonymizer
-
Use context to recognize personal initials and lowercase namesPossibly taken @lipikaramaswamy claimed this 10 days ago. Openbug
Difficulty 2/5 1-3 hours Newbie friendliness 67/100
NVIDIA-NeMo/Anonymizer#340 ·
Maintainers usually reply within 1 day
-
Clarify date validation for months, years, and partial datesPossibly taken @lipikaramaswamy claimed this 10 days ago. Openbug
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
NVIDIA-NeMo/Anonymizer#334 ·
Maintainers usually reply within 1 day
-
Replacement-map generation can silently omit a requested entity, causing the rewrite to be marked unavailablePossibly taken @dundysm claimed this 43 days ago. Openbug
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
NVIDIA-NeMo/Anonymizer#278 · 2 comments ·
Maintainers usually reply within 1 day
-
enhancement
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
NVIDIA-NeMo/Anonymizer#6 · 1 comment ·
Maintainers usually reply within 1 day
-
enhancement
Difficulty 5/5 Over a week Newbie friendliness 28/100
NVIDIA-NeMo/Anonymizer#377 ·
Maintainers usually reply within 1 day
All issues in NVIDIA-NeMo/Anonymizer
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
didi/helixharness#18 ·
-
request-theme
Difficulty 1/5 Under an hour Newbie friendliness 78/100
LizardByte/ThemerrDB#9883 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
NousResearch/hermes-agent#149885 ·
Maintainers usually reply within 1 day
-
Set cache_ok = True on GUID TypeDecorator to enable SQLAlchemy query cachingPossibly taken @patelshivani2283-lab claimed this today. Open
Difficulty 1/5 Under an hour Newbie friendliness 91/100
fedora-infra/anitya#2157 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
Project-MONAI/MONAI#9258 ·
Maintainers usually reply within 3 days