Edge Confidence Tiers in code-review-graph: EXTRACTED, INFERRED, and AMBIGUOUS Explained

Edge confidence tiers in code-review-graph categorize relationship certainty into three levels—EXTRACTED (direct static analysis), INFERRED (reasoned relationships), and AMBIGUOUS (uncertain matches)—each paired with a numeric confidence score between 0 and 1.

The tirth8205/code-review-graph repository implements a SQLite-backed knowledge graph that stores relationships between code elements as edges. Each edge carries an edge confidence tier that communicates how the relationship was established, allowing downstream analysis tools to weight connections appropriately based on their origin and reliability.

What Are Edge Confidence Tiers?

Every edge in the knowledge graph stores two critical fields in the database schema defined in code_review_graph/graph.py: a numeric confidence value (REAL) between 0 and 1, and a textual confidence_tier label. While the float quantifies certainty probability, the tier captures the provenance of that certainty—whether it came from direct parsing, intelligent inference, or ambiguous matching.

The schema defines strict defaults in the GraphEdge dataclass:

confidence: float = 1.0
confidence_tier: str = "EXTRACTED"

Database migration v9 (located in code_review_graph/migrations.py) formally introduced these columns to the edges table:

confidence REAL DEFAULT 1.0,
confidence_tier TEXT DEFAULT 'EXTRACTED'

The Three Confidence Tiers

The system recognizes three distinct tiers that classify edges based on how they were generated.

EXTRACTED (Direct Static Analysis)

Edges labeled EXTRACTED originate from direct static analysis performed by the parser. When the AST walker identifies a call site or explicit dependency, it creates an edge with this tier. Because these relationships are empirically present in the source code, they receive the highest default confidence of 1.0. The parser.py module emits these edges when it traverses abstract syntax trees and discovers concrete references between functions, classes, or modules.

INFERRED (Higher-Level Reasoning)

The INFERRED tier applies to edges created by higher-level resolvers that deduce relationships through reasoning about runtime behavior, event propagation, or indirect invocation patterns. These edges carry a confidence value below 1.0 (typically 0.9–0.99) to reflect the deductive nature of the connection. For example, the event_resolver.py module explicitly sets confidence_tier="INFERRED" and assigns a confidence of 0.95 when it determines that a function will be invoked as a consequence of event handling logic.

AMBIGUOUS (Uncertain Relationships)

AMBIGUOUS edges indicate that the resolver encountered multiple possible targets or could not definitively determine a specific relationship. This tier is reserved for situations involving runtime reflection, dynamic dispatch, or unclear binding targets. While the current codebase does not yet contain a concrete implementation emitting ambiguous edges, the schema supports this tier with intentionally lowered confidence values (commonly ≤ 0.6) to flag uncertain connections for future resolver implementations.

Implementing Edges with Different Tiers

The GraphStore.upsert_edge method in code_review_graph/graph.py writes both confidence fields to the SQLite database. Here are practical examples demonstrating each tier:

from code_review_graph.graph import GraphStore

# EXTRACTED edge from static analysis

with GraphStore("graph.db") as store:
    store.upsert_edge(
        kind="CALLS",
        source_qualified="my_pkg.module_a.func_a",
        target_qualified="my_pkg.module_b.func_b",
        file_path="my_pkg/module_a.py",
        line=42,
        extra={},
        confidence=1.0,
        confidence_tier="EXTRACTED"
    )

# INFERRED edge from event resolution

with GraphStore("graph.db") as store:
    store.upsert_edge(
        kind="CALLS",
        source_qualified="my_pkg.event_handler.handle",
        target_qualified="my_pkg.service.start",
        file_path="my_pkg/event_handler.py",
        line=108,
        extra={"event": "startup"},
        confidence=0.95,
        confidence_tier="INFERRED"
    )

# AMBIGUOUS edge for uncertain dynamic dispatch

with GraphStore("graph.db") as store:
    store.upsert_edge(
        kind="CALLS",
        source_qualified="my_pkg.dynamic.dispatch",
        target_qualified="my_pkg.unknown.possible_target",
        file_path="my_pkg/dynamic.py",
        line=77,
        extra={"reason": "runtime reflection"},
        confidence=0.5,
        confidence_tier="AMBIGUOUS"
    )

Summary

  • EXTRACTED edges represent direct observations from static parsing with confidence=1.0, defined as the default in graph.py.
  • INFERRED edges capture reasoned relationships from resolvers like event_resolver.py, typically using confidence values of 0.9–0.99.
  • AMBIGUOUS edges handle uncertain or multiple-target scenarios with lower confidence scores (≤ 0.6), supported by the schema for future extensibility.
  • Migration v9 added the confidence and confidence_tier columns to the SQLite database, enabling fine-grained probability tracking alongside categorical provenance.

Frequently Asked Questions

What is the default edge confidence tier in code-review-graph?

According to the GraphEdge dataclass in code_review_graph/graph.py, the default confidence_tier is EXTRACTED with a default confidence value of 1.0. These defaults apply when edges are created without explicit confidence parameters.

How does the event resolver assign confidence values?

The event_resolver.py module specifically marks edges with confidence_tier="INFERRED" and typically assigns confidence values around 0.95 when deducing event-driven relationships that are not explicitly visible in the static AST.

Can I create AMBIGUOUS edges with the current implementation?

Yes. While no current resolver in the repository automatically emits ambiguous edges, the schema defined in graph.py and established by migration v9 fully supports creating edges with confidence_tier="AMBIGUOUS" and reduced confidence values (e.g., 0.5) using the GraphStore.upsert_edge method.

Why are confidence tiers stored as text rather than integers?

The text-based confidence_tier column provides semantic clarity and extensibility. By using descriptive strings (EXTRACTED, INFERRED, AMBIGUOUS) rather than opaque integer codes, the database remains human-readable and allows future developers to introduce new tiers without modifying lookup tables or enum mappings.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →