How Graphify Performs PR Impact Analysis and Triage: A Technical Deep Dive
Graphify treats pull requests as enriched objects that map code changes against a knowledge graph to calculate blast radius, then leverages LLM-powered triage to automatically rank PRs by review priority.
The safishamsi/graphify repository provides an intelligent PR impact analysis and triage system that transforms raw GitHub pull requests into actionable intelligence. By combining graph topology analysis with AI-driven prioritization, Graphify reveals exactly which communities and nodes each PR touches, enabling maintainers to focus review efforts where they matter most.
The PRInfo Data Model as a First-Class Object
Graphify's architecture centers on the PRInfo class, which aggregates three distinct data streams:
- GitHub metadata: CI status, review decisions, and draft flags fetched via the
ghCLI. - Work-tree mapping: A dictionary linking branch names to local work-tree paths for rapid filesystem access.
- Graph-impact data: Community intersections, node counts, and blast-radius calculations derived from
graphify-out/graph.json.
The 8-Step Impact Analysis Workflow
The PR analysis pipeline executes through a coordinated sequence of functions defined in graphify/prs.py.
Fetching PRs and Detecting Base Branches
The process begins with fetch_prs() (lines 89-118), which executes gh pr list to retrieve open pull requests and instantiate PRInfo objects. Concurrently, _detect_default_branch() (lines 48-69) auto-detects the repository's default branch using gh repo view or git symbolic-ref, ensuring accurate base comparisons.
Work-Tree Mapping and Graph Loading
To map local development contexts, fetch_worktrees() (lines 92-106) parses git worktree list --porcelain output into a {branch: path} dictionary. The system then loads topological data via _load_graph_json() (lines 18-27), which reads graphify-out/graph.json while applying a size-cap security check via check_graph_file_size_cap from graphify/security.py.
Computing Graph Impact and Blast Radius
The core analysis occurs in attach_graph_impact() (lines 34-92). This function:
- Fetches changed files concurrently using
fetch_pr_files(). - Matches paths against the graph index using
_path_match, which tolerates both absolute and relative path formats. - Populates
communities_touched,nodes_affected, and generates a human-readableblast_radiusstring (e.g., "12 nodes / 3 communities").
Rendering the Impact Dashboard
Finally, render_dashboard() (lines 96-114) outputs a color-coded terminal table displaying each PR's blast radius and impact summary.
O(nodes + files) Graph Lookup Algorithm
Graphify optimizes impact calculation through one-time indexing of file_comms and file_count, ensuring that changed file lookups operate at O(nodes + files) complexity rather than quadratic time. The _path_match function normalizes path representations, treating src/foo.py and foo.py as identical entities during community matching.
Opus-Powered Triage and Backend Resolution
For automated prioritization, triage_with_opus() (lines 42-56) constructs textual prompts describing each actionable PR's impact characteristics, then streams ranked priorities through an LLM backend.
The backend selection logic in _resolve_triage_backend() (lines 58-73) follows this priority order:
- Explicit
GRAPHIFY_TRIAGE_BACKENDenvironment variable. - First available backend with valid API credentials (Claude, Kimi, OpenAI, Gemini, Ollama).
- Fallback to local
claude-cliif installed.
Model selection uses GRAPHIFY_TRIAGE_MODEL or defaults from _TRIAGE_MODEL_DEFAULTS defined in graphify/llm.py.
Command-Line Usage Examples
Execute impact analysis using the following commands:
# Display dashboard of all open PRs with impact calculations
graphify prs
# Generate AI-ranked triage list for review prioritization
graphify prs --triage
# Inspect specific PR details including changed files and impact
graphify prs 1234
Programmatic access to raw impact data:
from pathlib import Path
from graphify.prs import fetch_prs, attach_graph_impact
prs = fetch_prs()
graph_path = Path("graphify-out/graph.json")
labels = attach_graph_impact(prs, graph_path)
for pr in prs:
if pr.communities_touched:
print(f"PR #{pr.number} touches communities {pr.communities_touched} "
f"affecting {pr.nodes_affected} nodes → {pr.blast_radius}")
Summary
- Graphify's PR impact analysis and triage system treats pull requests as enriched
PRInfoobjects combining GitHub metadata, work-tree mappings, and graph topology data. - Impact calculation runs in O(nodes + files) time via indexed lookups in
attach_graph_impact()withingraphify/prs.py. - The blast radius metric quantifies PR scope as human-readable strings like "12 nodes / 3 communities".
- Opus-powered triage automatically ranks PRs by review priority using configurable LLM backends resolved via
_resolve_triage_backend(). - Integration endpoints in
graphify/serve.pyexpose the same functionality over HTTP for CI/CD pipelines.
Frequently Asked Questions
How does Graphify determine which graph communities a PR affects?
Graphify matches changed files against the knowledge graph index using _path_match in graphify/prs.py, which identifies intersecting communities while normalizing absolute and relative path formats. The results populate PRInfo.communities_touched and nodes_affected.
What LLM backends does Graphify support for triage ranking?
The system supports Claude (Opus), Kimi, OpenAI, Gemini, and Ollama, with selection controlled by GRAPHIFY_TRIAGE_BACKEND and model selection via GRAPHIFY_TRIAGE_MODEL. If no API keys are configured, it falls back to local claude-cli according to the logic in _resolve_triage_backend().
Why is the impact lookup O(nodes + files) instead of O(n²)?
Graphify pre-indexes the graph into file_comms and file_count structures during _load_graph_json(), allowing attach_graph_impact() to perform hashtable lookups rather than nested iterations when matching changed files against graph nodes.
Can I use Graphify's PR analysis in a CI/CD pipeline?
Yes. While the CLI provides the primary interface, graphify/serve.py exposes the same PR impact analysis and triage functionality via HTTP endpoints, enabling integration with automated build systems and custom dashboards.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →