mirror of
https://github.com/safishamsi/graphify.git
synced 2026-10-25 16:22:30 +00:00
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:
1 parent
6bba91fc65
commit
37efe877cf
2 files changed
+45
-2
No files matched your search
@@ -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.
|
||||
|
||||
@@ -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"}
|
||||
Reference in new issue
Block a user