# How Edge Confidence Scoring Differentiates Edge Types in code-review-graph

> Learn how edge confidence scoring in code-review-graph distinguishes extracted edges from inferred edges using confidence fields and tiers. Understand edge types clearly.

- Repository: [Tirth Kanani/code-review-graph](https://github.com/tirth8205/code-review-graph)
- Tags: internals
- Published: 2026-08-06

---

**Edge confidence scoring in code-review-graph uses a numeric `confidence` field paired with a `confidence_tier` tag to distinguish between `EXTRACTED` edges parsed directly from source code and `INFERRED` edges derived through post-processing resolvers.**

The `code-review-graph` project stores every relationship between code entities in a SQLite-backed graph database. Through a lightweight yet expressive edge confidence scoring system, the repository enables downstream tools to discriminate between directly observed code relationships and those inferred through language-specific analysis.

## The Confidence Schema: Two Columns Working Together

In [`code_review_graph/graph.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/graph.py), the `GraphEdge` dataclass defines the schema for every relationship. Lines 102‑104 introduce two critical fields:

- **`confidence`**: A floating-point value from 0 to 1 expressing certainty (defaults to `1.0`)
- **`confidence_tier`**: A categorical tag classifying the source of the information (defaults to `"EXTRACTED"`)

These columns were added by migration *v9* in [`code_review_graph/migrations.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/migrations.py) (lines 229‑238), which alters the `edges` table to support nuanced trust levels. This dual-column approach allows the system to store both a quantitative weight and a qualitative provenance for every edge.

## EXTRACTED vs INFERRED: How Edge Types Are Classified

Edge confidence scoring categorizes every relationship into one of two primary tiers based on how the edge enters the system.

### EXTRACTED: Directly Observed Relationships

Edges created by the `parser` module carry the **`EXTRACTED`** tier. These relationships—such as function calls, imports, and inheritance links—are captured verbatim from the Abstract Syntax Tree (AST) during the initial code scan. Because they reflect concrete syntax present in the source files, they retain the default `confidence` of `1.0` and remain labeled as `EXTRACTED` unless overwritten by later analysis.

### INFERRED: Post-Processed Relationships

When the parser encounters ambiguous references (for example, an unqualified class name like `Bar` instead of `src/bar.py::Bar`), the system initially stores an `EXTRACTED` edge with an unresolved target. The **`INFERRED`** tier is assigned by post-processing resolvers that disambiguate these references.

The most common transformation occurs in [`code_review_graph/scoped_resolver.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/scoped_resolver.py). Lines 78‑81 explicitly write `confidence_tier = 'INFERRED'` after resolving an ambiguous target to its fully qualified name. Similarly, [`code_review_graph/event_resolver.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/event_resolver.py) (lines 106‑108) sets this tier when injecting confidence information for dynamically discovered edges.

## How Resolvers Update Edge Confidence

The transition from `EXTRACTED` to `INFERRED` follows a specific lifecycle. First, the parser inserts a raw edge with default values:

```python

# Insert a raw CALLS edge – automatically receives EXTRACTED tier

store.insert_edge(
    kind="CALLS",
    source_qualified="src/module.py::Foo",
    target_qualified="Bar",               # Unresolved target

    file_path="src/module.py",
    line=42,
    extra=json.dumps({}),
)

# Result: confidence=1.0, confidence_tier="EXTRACTED"

```

After initial extraction, the scoped resolver performs language-specific disambiguation:

```python
from code_review_graph import scoped_resolver

# Resolve ambiguous references and update tiers

scoped_resolver.resolve_scoped_calls(store)

# After resolution:

# - target_qualified becomes "src/bar.py::Bar"

# - confidence_tier becomes "INFERRED"

# - extra field gains "scoped_resolved": True

```

During this process, the resolver may also adjust the numeric `confidence` value, though it typically remains `1.0` unless the resolution involves heuristic matching.

## Practical Impact on Graph Queries

Edge confidence scoring directly affects downstream analysis tools. The graph's impact engine multiplies edge weights by the numeric `confidence` value when calculating paths. This mechanism allows tools like `get_impact_radius_tool` to prioritize high-confidence routes while preserving lower-confidence paths for inspection.

Query filters can leverage the `confidence_tier` column to select only `INFERRED` edges, which have been disambiguated by resolvers and therefore offer more precise targeting than raw `EXTRACTED` edges. This distinction proves critical for audit trails in automated code-review workflows, where developers need to distinguish between directly observed syntax and derived relationships.

## Summary

- **Dual-column design**: The schema stores `confidence` (numeric 0‑1) and `confidence_tier` (textual tag) in [`code_review_graph/graph.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/graph.py) via migration v9.
- **EXTRACTED tier**: Default state for edges parsed directly from source code AST by the parser module.
- **INFERRED tier**: Assigned by [`scoped_resolver.py`](https://github.com/tirth8205/code-review-graph/blob/main/scoped_resolver.py) and [`event_resolver.py`](https://github.com/tirth8205/code-review-graph/blob/main/event_resolver.py) when post-processing resolves ambiguous references or discovers dynamic relationships.
- **Query benefits**: The tier system enables precision filtering in impact analysis, while the numeric confidence allows weighted path scoring across the graph.

## Frequently Asked Questions

### What is the default confidence value for new edges in code-review-graph?

By default, every new edge inserted into the graph receives a `confidence` value of `1.0` and a `confidence_tier` of `"EXTRACTED"`. These defaults are defined in the schema at [`code_review_graph/graph.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/graph.py) lines 102‑104 and applied by the migration in [`code_review_graph/migrations.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/migrations.py) lines 229‑238.

### How does the scoped resolver change an edge's confidence tier?

The [`scoped_resolver.py`](https://github.com/tirth8205/code-review-graph/blob/main/scoped_resolver.py) module updates edges by resolving ambiguous targets (such as unqualified class names) to fully qualified identifiers. At lines 78‑81, it explicitly sets `confidence_tier = 'INFERRED'` while preserving or adjusting the numeric confidence score, thereby marking the edge as processed rather than raw extracted data.

### Why would a query prefer INFERRED edges over EXTRACTED edges?

`INFERRED` edges have been processed by language-specific resolvers that disambiguate targets and verify relationships through heuristic analysis. When performing impact-radius or flow analysis, queries prefer these edges because they represent verified, qualified relationships rather than potentially ambiguous raw syntax references captured during initial parsing.

### Where are the confidence columns defined in the database schema?

The `confidence` and `confidence_tier` columns are defined in the `GraphEdge` dataclass within [`code_review_graph/graph.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/graph.py) (lines 102‑104). They were added to the SQLite `edges` table by migration version 9 located in [`code_review_graph/migrations.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/migrations.py) (lines 229‑238).