fix(markdown): keep owner evidence when the edge already exists

The review bot flagged a real hazard in the owner-evidence bookkeeping: a
mention whose `references` edge is already in the graph returned early, so
the document never recorded that it cites the target. A later bare method
mention in the same document then lost its owner and was dropped.

`_add` now records the cited target before it decides whether the edge has
to be written, so the evidence survives an edge that is already there.

The pipeline cannot reach that state today (the resolver is handed a fresh
edge list, and the incremental context only carries contains/method/
inherits/imports edges), so this is hardening rather than a fix for a
reachable failure. The regression test drives the resolver directly with a
pre-existing class edge.
This commit is contained in:
nothariharan committed 2026-10-21 17:00:00 +05:30
1 parent 6bba91fc65
commit 37efe877cf
2 files changed
+45 -2

No files matched your search

+9 -2
View File
@@ -229,7 +229,14 @@ def resolve_markdown_mentions(
def _add(rc: dict, target: str | None, confidence: str, score: float) -> None:
caller = str(rc.get("caller_nid", ""))
if target is None or target == caller or (caller, target) in existing:
if target is None or target == caller:
return
doc = _posix(str(rc.get("source_file", "")))
if (caller, target) in existing:
# The edge is already in the graph, but this document still CITES that
# target, so it stays on record as owner evidence for a later method
# mention in the same document (#4609 review finding).
cited_targets.setdefault(doc, set()).add(target)
return
existing.add((caller, target))
all_edges.append({
@@ -243,7 +250,7 @@ def resolve_markdown_mentions(
"source_location": rc.get("source_location"),
"weight": 1.0,
})
cited_targets.setdefault(_posix(str(rc.get("source_file", ""))), set()).add(target)
cited_targets.setdefault(doc, set()).add(target)
# Pass 1: explicit evidence resolves on its own — a cited path, a dotted
# qualifier chain, or a trailing (). Record those targets per document.
+36
View File
@@ -346,3 +346,39 @@ def test_owner_cited_in_another_document_does_not_count(tmp_path):
b = _node(r, "B")
assert {t for (s, t) in _references(r) if s == b["id"]} == set()
def test_owner_evidence_survives_an_edge_that_already_exists():
"""A mention whose edge is already in the graph still counts as citing its target.
The resolver skips an edge that is already there, but the document has still
cited that symbol, so the evidence must stay on record for a later method
mention in the same document (#4609, review finding on the PR).
"""
from graphify.markdown_resolution import resolve_markdown_mentions
per_file = [{"raw_calls": [
{"caller_nid": "doc_notes", "callee": "HandlerResult", "language": "markdown",
"context": "HandlerResult", "source_file": "notes.md", "source_location": "L3"},
{"caller_nid": "doc_notes", "callee": "successWithWarnings", "language": "markdown",
"context": "successWithWarnings", "source_file": "notes.md", "source_location": "L3"},
]}]
nodes = [
{"id": "doc_notes", "label": "Notes", "file_type": "document",
"source_file": "notes.md"},
{"id": "handler_handlerresult", "label": "HandlerResult", "file_type": "code",
"_callable": True, "_callable_class": True, "source_file": "handler.py"},
{"id": "handler_handlerresult_successwithwarnings", "label": ".successWithWarnings()",
"file_type": "code", "_callable": True, "source_file": "handler.py"},
]
edges = [
{"source": "handler_handlerresult",
"target": "handler_handlerresult_successwithwarnings", "relation": "method"},
# The class reference edge is already in the graph.
{"source": "doc_notes", "target": "handler_handlerresult", "relation": "references"},
]
resolve_markdown_mentions(per_file, nodes, edges)
assert ("doc_notes", "handler_handlerresult_successwithwarnings") in {
(e["source"], e["target"]) for e in edges if e.get("relation") == "references"}