Edge Confidence Scoring in code-review-graph: EXTRACTED vs INFERRED vs AMBIGUOUS Explained
Edge confidence scoring in code-review-graph assigns every relationship edge one of three tiers—EXTRACTED, INFERRED, or AMBIGUOUS—to indicate how certain the static analyzer is about the connection's existence.
The tirth8205/code-review-graph project models codebase architecture as a graph of structural relationships, but static analysis of dynamic languages cannot always resolve connections with absolute certainty. Edge confidence scoring provides a three-tier taxonomy that tells downstream tools exactly how each relationship was derived, enabling precise impact analysis and risk calculation when tracing dependencies across Python or JavaScript projects.
The Three Confidence Tiers
Every edge stored in the graph database includes a confidence_tier column that classifies the relationship's reliability. According to the source code in code_review_graph/graph.py (lines 70–73), the tier is stored as a TEXT field with a default value of 'EXTRACTED', alongside a numeric confidence REAL column defaulting to 1.0.
The three tiers represent distinct levels of analytical certainty:
- EXTRACTED: The edge was parsed directly from the abstract syntax tree (AST) and represents an explicit reference in source code, such as a literal function call
foo()or a concreteimportstatement. - INFERRED: The edge was heuristically deduced because static analysis could not find a concrete reference, but contextual clues suggest a likely relationship, such as dynamic dispatch or a function passed as a callback.
- AMBIGUOUS: The analyzer identified multiple possible targets for a single reference and cannot determine which candidate is correct, often occurring with overloaded functions or wildcard imports.
How Edge Confidence Is Derived
EXTRACTED: Direct AST Analysis
Edges marked as EXTRACTED come from unambiguous syntactic evidence. When the parser encounters explicit calls or inheritance declarations, it creates an edge with this tier. This is the most reliable classification and serves as the default for all edges unless the analyzer encounters uncertainty.
INFERRED: Heuristic Resolution
When analyzing dynamic patterns, the system creates INFERRED edges. In code_review_graph/event_resolver.py at line 107, the resolver explicitly assigns the INFERRED tier to edges representing dynamic relationships that lack direct AST evidence but match heuristic patterns. This commonly occurs with duck-typed code, metaprogramming constructs, or callbacks where the target function isn't explicitly named at the call site.
AMBIGUOUS: Unresolved Multiple Candidates
AMBIGUOUS edges arise during name resolution when the analyzer finds several plausible definitions for a single reference. Rather than dropping the potential relationship, the system preserves the edge with this uncertainty marker. This tier frequently appears with wildcard imports or polymorphic dispatch where the concrete type cannot be statically determined.
Querying and Filtering by Confidence Tier
Inspecting Edge Metadata
The query_graph_tool exposes the confidence tier for every relationship. When querying callers or dependencies, the returned JSON includes a confidence_tier field that you can inspect programmatically:
from code_review_graph.mcp_tools import query_graph_tool
result = query_graph_tool(
pattern="callers_of",
qualified_name="my_module.my_function",
)
for edge in result["edges"]:
print(
f"{edge['source_qualified']} → {edge['target_qualified']}: "
f"tier={edge['confidence_tier']}"
)
Filtering for High-Confidence Edges
Downstream analysis tools often exclude uncertain connections to reduce false positives. You can filter result sets to include only directly extracted relationships:
high_conf_edges = [
e for e in result["edges"]
if e["confidence_tier"] == "EXTRACTED"
]
This pattern ensures that impact radius calculations and change detection logic rely solely on explicit, syntactically verified dependencies.
Database Schema Storage
The SQLite schema defines the confidence tier in code_review_graph/graph.py (lines 70–71) and was added via migration in code_review_graph/migrations.py (lines 234–236):
CREATE TABLE IF NOT EXISTS edges (
source_qualified TEXT NOT NULL,
target_qualified TEXT NOT NULL,
edge_type TEXT NOT NULL,
confidence REAL DEFAULT 1.0,
confidence_tier TEXT DEFAULT 'EXTRACTED',
PRIMARY KEY (source_qualified, target_qualified, edge_type)
);
The confidence_tier field allows tools like detect_changes_tool to weight edges differently when computing risk scores, biasing results toward more certain relationships even though all edges carry a default numeric confidence of 1.0.
Why Confidence Tiers Matter for Impact Analysis
The FAQ documentation in docs/FAQ.md (lines 45–48) explains that dynamic dispatch, metaprogramming, and duck typing inherently produce uncertainty in static analysis. Without tiered confidence scoring, tools would either miss potential dependencies entirely or overwhelm users with false positives.
By distinguishing between EXTRACTED, INFERRED, and AMBIGUOUS relationships, code-review-graph enables precise control over dependency graphs. Security scanners can ignore inferred call chains, while refactoring tools might surface ambiguous edges for manual review. This granularity is essential for maintaining accurate codebase intelligence in dynamic language ecosystems.
Summary
- Edge confidence scoring classifies every relationship in the codebase graph as EXTRACTED, INFERRED, or AMBIGUOUS based on analytical certainty.
- EXTRACTED edges represent direct AST parses and provide the highest reliability, stored by default in
code_review_graph/graph.py. - INFERRED edges capture heuristic relationships from dynamic patterns, created in
code_review_graph/event_resolver.py. - AMBIGUOUS edges indicate multiple possible targets, preserving potential connections without asserting certainty.
- Downstream tools filter by
confidence_tierto bias impact analysis toward verified dependencies and reduce noise from dynamic language features.
Frequently Asked Questions
What is the default confidence tier for new edges?
By default, all edges created in code_review_graph receive the EXTRACTED tier and a numeric confidence score of 1.0. The database schema in code_review_graph/graph.py defines these defaults at lines 70–71, ensuring that edges are treated as reliable unless the analyzer specifically encounters ambiguity.
How does edge confidence scoring handle dynamic dispatch in Python?
Dynamic dispatch creates INFERRED edges because the concrete target of a method call cannot be resolved statically from the AST alone. When the event_resolver.py module (line 107) encounters patterns like duck typing or callbacks, it marks these relationships as INFERRED to signal that they rely on heuristic analysis rather than direct parsing.
Can I filter graph queries to exclude AMBIGUOUS edges?
Yes. When using query_graph_tool or processing edge lists directly, filter the results to include only edges where confidence_tier == "EXTRACTED". This pattern ensures that impact analysis, change detection, and risk scoring rely exclusively on unambiguous, syntactically verified relationships rather than uncertain candidates.
Where is the confidence tier stored in the database?
The confidence_tier column lives in the edges table of the SQLite database, defined in code_review_graph/graph.py at lines 70–73. It stores the tier as a TEXT value ('EXTRACTED', 'INFERRED', or 'AMBIGUOUS'), while the accompanying confidence column stores a real number defaulting to 1.0. The column was added via the migration script in code_review_graph/migrations.py (lines 234–236).
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →