mirror of
https://github.com/safishamsi/graphify.git
synced 2026-09-24 14:35:46 +00:00
Merge pull request #1248 from teemow/fix/dedup-pass2-winner-union
fix(dedup): pick pass-2 winner from the verified pair only (#1247)
This commit is contained in:
+5
-3
@@ -293,9 +293,11 @@ def deduplicate_entities(
|
||||
sf_b = neighbor.get("source_file") or ""
|
||||
if sf_a != sf_b:
|
||||
continue
|
||||
all_group = norm_to_nodes.get(norm_label, [node]) + \
|
||||
norm_to_nodes.get(neighbor_norm, [neighbor])
|
||||
winner = _pick_winner(all_group)
|
||||
# Pick the winner from the verified pair only. Selecting it
|
||||
# from the union of both normalized-label groups pulls
|
||||
# never-compared nodes (same label, different source_file)
|
||||
# into the merge, bypassing the #1046/#1178 guards.
|
||||
winner = _pick_winner([node, neighbor])
|
||||
uf.union(winner["id"], node_id)
|
||||
uf.union(winner["id"], neighbor_id)
|
||||
fuzzy_merges += 1
|
||||
|
||||
@@ -208,6 +208,36 @@ def test_prefix_extension_symbols_not_merged():
|
||||
)
|
||||
|
||||
|
||||
def test_pass2_winner_union_does_not_pull_in_uncompared_same_label_nodes():
|
||||
"""Pass 2's winner selection must consider only the verified pair (#1247).
|
||||
|
||||
Picking the winner from the union of both normalized-label groups pulls
|
||||
never-compared nodes into the merge: here A ("Session Manager", auth.md)
|
||||
and B ("Session Manager", billing.md) are deliberately kept distinct by
|
||||
the cross-file identical-label guards (#1046, #1178), yet when the
|
||||
A-C fuzzy match ("Session Managr" typo) fires, _pick_winner over
|
||||
[A, B, C] selects B (shortest id) and unions B with both A and C —
|
||||
merging B although it was never compared against anything.
|
||||
"""
|
||||
nodes = [
|
||||
{"id": "session_manager_auth", "label": "Session Manager",
|
||||
"source_file": "auth.md"},
|
||||
{"id": "sm", "label": "Session Manager",
|
||||
"source_file": "billing.md"},
|
||||
{"id": "session_managr_notes", "label": "Session Managr",
|
||||
"source_file": "notes.md"},
|
||||
]
|
||||
result_nodes, _ = deduplicate_entities(nodes, [], communities={})
|
||||
ids = {n["id"] for n in result_nodes}
|
||||
# B must survive as a distinct node: identical label across different
|
||||
# source files is exactly what the #1046/#1178 guards keep separate.
|
||||
assert "sm" in ids, (
|
||||
"uncompared cross-file node 'sm' was absorbed via pass-2 winner-union"
|
||||
)
|
||||
# The verified fuzzy pair (A, C) still merges — only one of them survives.
|
||||
assert len(result_nodes) == 2
|
||||
|
||||
|
||||
def test_prefix_guard_does_not_block_same_length_typos():
|
||||
"""The prefix-extension guard must not fire for same-length pairs — only strict
|
||||
prefix-extensions (one is a substring of the other) should be blocked (#1201).
|
||||
|
||||
Reference in New Issue
Block a user