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

> Discover how execution flow detection traces call chains in code-review-graph. Learn how entry points are identified and call chains are mapped for analysis.

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

---

**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`](https://github.com/tirth8205/code-review-graph/blob/main/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:

```python
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`](https://github.com/tirth8205/code-review-graph/blob/main/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`](https://github.com/tirth8205/code-review-graph/blob/main/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.