How Execution Flow Detection Traces Call Chains in code-review-graph

Execution flow detection identifies entry points by analyzing decorator patterns and function names, then performs a breadth-first search along CALLS edges to map complete call chains for criticality scoring.

The code-review-graph repository implements a static analysis pipeline that reconstructs program execution paths to prioritize security reviews. Execution flow detection serves as the core mechanism that discovers where code execution begins and follows outgoing invocations to build traversable call graphs stored in GraphStore.

How Execution Flow Detection Identifies Entry Points

The detection process begins in code_review_graph/flows.py where detect_entry_points (lines 64‑88) scans the graph for functions that initiate execution. A node qualifies as an entry point when it meets any of three distinct criteria.

Root Functions Without Callers

A function becomes a true root when no other function calls it. The algorithm builds a comprehensive set of all call targets using store.get_all_call_targets (line 78), then filters for Function or Test nodes absent from this set.

Framework Decorator Patterns

The system recognizes framework-specific entry points through _has_framework_decorator (lines 29‑40). This helper checks if a node carries decorators matching regex patterns defined in _FRAMEWORK_DECORATOR_PATTERNS, identifying handlers for web frameworks, task queues, or CLI entry points.

Conventional Naming Conventions

When decorators are absent, _matches_entry_name (lines 44‑50) applies _ENTRY_NAME_PATTERNS to detect conventional entry names like main, run, or execute. This captures standalone scripts that lack explicit framework markers.

Test File Exclusion

By default, the pipeline excludes test files via _is_test_file (lines 54‑61) unless the include_tests=True parameter is passed to trace_flows. This prevents test harnesses from polluting production flow analysis.

BFS Traversal of Call Chains

Once entry points are established, execution flow detection traces outgoing invocations using _trace_single_flow (lines 22‑64) with a breadth-first search strategy.

The FlowAdjacency Structure

The traversal relies on FlowAdjacency, populated by store.load_flow_adjacency, which exposes calls_out—a dictionary mapping qualified names to sets of callee qualified names. This adjacency representation enables efficient forward traversal without repeated database queries.

Queue-Based Path Expansion

Starting with a queue containing the entry point's qualified name, the algorithm (lines 41‑58) dequeues nodes iteratively, expands their outgoing CALLS edges via calls_out, and enqueues unvisited targets. During traversal, the system records:

  • path_ids: Node identifiers in visitation order
  • path_qnames: Fully qualified names forming the call chain
  • actual_depth: Maximum BFS depth reached

When the path contains multiple nodes, the function assembles a flow dictionary (lines 69‑79) capturing the complete execution sequence.

Criticality Scoring and Flow Ranking

The trace_flows function (lines 84‑100) orchestrates the complete pipeline. It first loads the adjacency structure once for efficiency, then invokes _trace_single_flow for each discovered entry point. Results undergo scoring via compute_criticality (lines 24‑93), which evaluates:

  • File spread: Distribution across multiple modules
  • External calls: Invocations outside the codebase
  • Security keywords: Presence of sensitive operations
  • Test coverage gaps: Execution paths lacking test validation
  • Depth: Length of the call chain

The weighted aggregation produces a 0.0‑1.0 criticality score. Finally, trace_flows sorts flows by this score (line 115) and returns the prioritized list.

Practical Implementation Example

To trace execution flows in a parsed repository:

from code_review_graph.graph import GraphStore
from code_review_graph.flows import trace_flows, get_flows

# Initialize populated graph store

store = GraphStore(db_path=":memory:")

# Trace all execution flows (excluding test entry points)

all_flows = trace_flows(store, max_depth=15, include_tests=False)

# Retrieve top-5 most critical flows

top_five = get_flows(store, sort_by="criticality", limit=5)
for flow in top_five:
    print(f"Flow {flow['name']} – criticality {flow['criticality']}")

For incremental analysis after code changes, use incremental_trace_flows(store, changed_files) to re-trace only flows intersecting modified files.

Summary

  • Entry point discovery in code_review_graph/flows.py combines root detection, decorator analysis, and naming conventions to locate execution starts.
  • BFS traversal via _trace_single_flow follows CALLS edges through FlowAdjacency to reconstruct complete call chains.
  • Criticality scoring weights file spread, security keywords, and test coverage to prioritize high-impact flows.
  • Orchestration through trace_flows handles batch processing and result sorting for downstream consumption.

Frequently Asked Questions

What qualifies as an entry point in code-review-graph?

An entry point is any Function or Test node with no incoming CALLS edges, a framework decorator matching _FRAMEWORK_DECORATOR_PATTERNS, or a name matching _ENTRY_NAME_PATTERNS. The detect_entry_points function evaluates these criteria in flows.py (lines 64‑88).

How does the BFS traversal handle cyclic call chains?

The _trace_single_flow implementation tracks visited nodes during queue processing (lines 41‑58), ensuring each qualified name is processed only once. This prevents infinite loops when encountering recursive or circular call patterns while preserving the first-discovered path.

What factors determine the criticality score of an execution flow?

The compute_criticality function (lines 24‑93) calculates scores based on file spread across modules, external library calls, security-sensitive keyword presence, gaps in test coverage, and maximum call depth. Each factor carries a configurable weight contributing to the final 0.0‑1.0 score.

Can execution flow detection include test files as entry points?

Yes. By default, _is_test_file (lines 54‑61) filters out test files, but passing include_tests=True to trace_flows includes them in the entry point scan. This is useful when analyzing test coverage or tracing test-specific execution paths.

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 →