# How Execution Flows Are Detected and Prioritized by Criticality in code-review-graph

> Discover how code-review-graph detects execution flows and prioritizes them by criticality. Learn about its BFS tracing, weighted scoring, and gap analysis for better code quality.

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

---

**The code-review-graph library identifies execution entry points using framework decorators and naming conventions, performs a breadth-first search to trace call paths, and calculates a weighted criticality score from 0.0 to 1.0 based on file spread, security sensitivity, and test coverage gaps.**

The `tirth8205/code-review-graph` repository provides a static analysis toolkit that maps execution flows through codebases to highlight high-risk paths for review. Understanding how the system detects entry points and quantifies criticality helps teams prioritize code review efforts on the most impactful logic paths.

## Detecting Entry Points in code-review-graph

Entry point detection drives the entire analysis pipeline. In [`code_review_graph/flows.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/flows.py), the `detect_entry_points` function (lines 64–78) identifies starting nodes by evaluating three distinct criteria.

### True Root Detection

A node qualifies as a true root if it has no incoming `CALLS` edges. The algorithm builds a set called `called_qnames` containing all target qualified names from `CALLS` edges, then verifies whether the node's qualified name exists in this set. Nodes absent from the set represent uncalled functions that potentially serve as application entry points.

### Framework Decorator Patterns

The system recognizes framework-specific decorators through `_has_framework_decorator(node)`, which scans the node's `decorators` metadata against `_FRAMEWORK_DECORATOR_PATTERNS`. This list includes patterns for Flask, FastAPI, Click, Spring, and other common web and CLI frameworks, automatically flagging decorated functions as entry points regardless of their call graph position.

### Conventional Naming Conventions

The `_matches_entry_name(node)` helper checks against `_ENTRY_NAME_PATTERNS` and `_LANGUAGE_ENTRY_NAME_PATTERNS`, identifying names like `main`, `__main__`, `test_*`, `on_*`, `lambda_handler`, and Android lifecycle methods. Any function or test node matching these patterns joins the `entry_points` list (lines 71–78).

## Tracing Execution Flows with BFS Traversal

Once entry points are identified, `trace_flows` initiates path discovery by calling `_trace_single_flow` (lines 22–30) for each starting node.

The tracer performs a **forward BFS** on the `CALLS` adjacency structure (`adj.calls_out`), respecting a configurable `max_depth` parameter that defaults to 15 levels. During traversal, the algorithm accumulates node IDs and qualified names in `path_ids` and `path_qnames`, tracking visited nodes to prevent cycles. Single-node flows are discarded as trivial (lines 60–62).

Each resulting flow dictionary contains metadata including `name`, `entry_point`, `path`, `depth`, `node_count`, `file_count`, and an initial `criticality` value of 0.0 (lines 70–79).

## Computing Criticality Scores for Prioritization

The `compute_criticality` function (lines 24–93) in [`code_review_graph/flows.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/flows.py) transforms flow metadata into a prioritized score between **0.0 and 1.0** using five weighted factors:

- **File spread (30%)**: Calculated as `min((file_count‑1)/4, 1)`, rewarding flows that touch multiple files
- **External calls (20%)**: Computed as `min(external_count/5, 1)`, penalizing dependencies on unanalyzed code
- **Security sensitivity (25%)**: Derived from `constants.SECURITY_KEYWORDS` matches in node names, calculated as `min(security_hits/len(nodes), 1)`
- **Test coverage gap (15%)**: Represented as `1 - coverage`, where coverage measures nodes with `TESTED_BY` relationships
- **Depth (10%)**: Scored as `min(depth/10, 1)`, favoring deeper execution paths

The final score equals the weighted sum of these components (lines 86–92), rounded to four decimal places before storage (lines 80–81).

## Persisting and Querying Flow Data

After computation, `store_flows` persists flow records to SQLite tables `flows` and `flow_memberships`, linking nodes to their respective execution paths.

For retrieval, `get_flows` (lines 88–106) returns flows sorted by `criticality` by default, surfacing the highest-risk paths first. For CI/CD integration, `incremental_trace_flows` (lines 58–78) retraces only flows intersecting changed files, reducing analysis time for large repositories during incremental reviews.

## Code Example: Detecting and Prioritizing Flows

```python
from code_review_graph.graph import GraphStore
from code_review_graph.flows import trace_flows, get_flows, incremental_trace_flows

# 1️⃣ Load the graph store (assume an existing SQLite DB at `mydb.sqlite`).

store = GraphStore(sqlite_path="mydb.sqlite")

# 2️⃣ Full flow detection and scoring (default depth = 15).

all_flows = trace_flows(store)          # → list of dicts, each with a `criticality` field

print(f"Found {len(all_flows)} execution flows")
print("Top‑3 most critical flows:")
for fl in all_flows[:3]:
    print(f"- {fl['name']} (criticality={fl['criticality']})")

# 3️⃣ Query stored flows (e.g., the 10 most critical ones).

top_stored = get_flows(store, limit=10)
for f in top_stored:
    print(f"{f['name']} → criticality {f['criticality']}")

# 4️⃣ Incremental re‑trace after editing a few files.

changed = ["src/web/app.py", "src/services/payment.py"]
retracked = incremental_trace_flows(store, changed_files=changed)
print(f"Re‑traced {retracked} flows that touched changed files")

```

This snippet demonstrates the core API: `trace_flows` for full analysis, `get_flows` for retrieval, and `incremental_trace_flows` for efficient re-analysis after code changes.

## Summary

- **Entry detection** relies on three criteria: uncalled roots, framework decorators, and conventional naming patterns defined in [`code_review_graph/flows.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/flows.py)
- **Flow tracing** uses forward BFS with a default depth limit of 15, filtering out trivial single-node paths
- **Criticality scoring** weights file spread (30%), security sensitivity (25%), external calls (20%), test gaps (15%), and depth (10%) into a 0.0–1.0 scale
- **Persistence** uses SQLite tables `flows` and `flow_memberships`, with incremental tracing available for optimized CI/CD workflows

## Frequently Asked Questions

### What defines an entry point in code-review-graph?

An entry point is any Function or Test node that satisfies at least one of three conditions: it has no incoming `CALLS` edges (a true root), it carries a framework decorator matching patterns in `_FRAMEWORK_DECORATOR_PATTERNS`, or its name matches conventional patterns like `main`, `test_*`, or `lambda_handler`. The `detect_entry_points` function evaluates these criteria against the graph's nodes to seed the flow analysis.

### How is the criticality score calculated?

The criticality score ranges from 0.0 to 1.0 and combines five weighted factors computed in `compute_criticality`: file spread (30%), security sensitivity based on keyword matches (25%), external call density (20%), test coverage gaps (15%), and execution depth (10%). Each factor normalizes to a 0–1 scale before the weighted sum produces the final priority value.

### When should I use incremental tracing versus full flow detection?

Use `incremental_trace_flows` when analyzing pull requests or commits that modified specific files, as it retraces only flows touching the changed files rather than the entire codebase. Full `trace_flows` detection remains appropriate for initial database creation or comprehensive audits where the complete call graph might have shifted.

### Which security keywords affect the criticality calculation?

The security sensitivity factor references `constants.SECURITY_KEYWORDS` to identify sensitive operations. While the specific keyword list resides in [`code_review_graph/constants.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/constants.py), typical entries include patterns related to authentication, authorization, encryption, and input validation that appear in node qualified names or function names.