cd /news/ai-tools/what-if-pull-requests-had-an-explain… Β· home β€Ί topics β€Ί ai-tools β€Ί article
[ARTICLE Β· art-146407] src=github.com β†— pub= topic=ai-tools verified=true sentiment=Β· neutral

What If Pull Requests Had an Explain Command?

PR Explain, an AI-assisted service that turns a GitHub Pull Request into an evidence-backed explanation, performs deterministic code analysis to build a structured change graph, collect evidence, and determine potential impact before an AI model narrates the findings. The service analyzes changed files, symbols, imports, call and symbol relationships, line-level evidence, and revision-to-revision changes, then posts the explanation back to the Pull Request as a GitHub comment. Its pipeline runs from a GitHub App webhook through a FastAPI API to a background worker that fetches the repository snapshot, analyzes the diff, parses symbols, builds the change graph, collects evidence, analyzes impact, and persists claims into an explanation packet.

read17 min views3 publishedOct 6, 2026
What If Pull Requests Had an Explain Command?
Image: Michielbdejong (auto-discovered)

PR Explain is an AI-assisted Pull Request explanation service that turns a GitHub Pull Request into an evidence-backed explanation of what changed, why it changed, and what parts of the codebase may be affected.

The core idea is simple:

PR Explain is like SQL EXPLAIN for Pull Requests.

Instead of asking an AI model to blindly read a Pull Request and guess what happened, PR Explain first performs deterministic code analysis, builds a structured change graph, collects evidence, and determines potential impact. The AI model then turns those facts into a human-readable explanation.

If you've used EXPLAIN or EXPLAIN ANALYZE in SQL, the easiest way to understand PR Explain is to think of it as the same concept applied to code changes.

For example:

EXPLAIN
SELECT *
FROM users
WHERE email = 'alice@example.com';

The database doesn't ask an AI model to guess what the query does.

Instead, the database analyzes the query and produces a structured execution plan describing things such as:

  • Which tables are accessed
  • Which indexes may be used
  • How operations are connected
  • The expected execution strategy
  • Potentially expensive operations

PR Explain applies the same philosophy to Pull Requests.

SQL Query
    β”‚
    β–Ό
Query Planner
    β”‚
    β–Ό
Execution Plan
    β”‚
    β–Ό
Human Understanding
Pull Request
    β”‚
    β–Ό
Code Change Analyzer
    β”‚
    β–Ό
Change Graph + Evidence + Impact
    β”‚
    β–Ό
AI Explanation
    β”‚
    β–Ό
Human Understanding

The important distinction is:

The AI is not the analyzer.

The deterministic analysis pipeline is responsible for discovering what actually changed.

The AI model is responsible for explaining those discovered facts.

A generic AI code-review system might look like:

Pull Request
     β”‚
     β–Ό
    LLM
     β”‚
     β–Ό
"Here's what I think changed..."

PR Explain instead follows:

Pull Request
     β”‚
     β–Ό
Deterministic Analysis
     β”‚
     β”œβ”€β”€ Changed files
     β”œβ”€β”€ Changed symbols
     β”œβ”€β”€ Imports
     β”œβ”€β”€ Calls
     β”œβ”€β”€ Relationships
     β”œβ”€β”€ Evidence
     └── Impact
              β”‚
              β–Ό
      Explanation Packet
              β”‚
              β–Ό
          AI Model
              β”‚
              β–Ό
     Human-readable explanation

This makes the AI model primarily a narrator, rather than the source of truth.

For example, if a Pull Request changes:

PaymentService.process_payment()
        β”‚
        β”œβ”€β”€ PaymentRepository.create()
        β”‚
        └── EventPublisher.publish()

PR Explain first determines those relationships from the repository and Pull Request.

The AI then receives the resulting evidence and can explain:

This change modifies payment processing and affects both persistence and event publishing. The new behavior therefore has potential impact on the payment data path as well as downstream consumers of the payment event.

The model is explaining relationships that the analysis pipeline has already established rather than inventing them.

PR Explain analyzes Pull Requests and produces an explanation based on the actual repository contents and changes.

The analysis includes:

  • Changed files
  • Changed symbols
  • Functions and classes
  • Imports
  • Call relationships
  • Symbol relationships
  • Relevant files outside the diff
  • Line-level evidence
  • Potential impact
  • Claims about the change
  • Revision-to-revision changes

The resulting explanation can be viewed in the web application and posted back to the Pull Request as a GitHub comment.

A Pull Request moves through the following pipeline:

GitHub Pull Request
        β”‚
        β–Ό
GitHub App Webhook
        β”‚
        β–Ό
FastAPI API
        β”‚
        β–Ό
Background Job
        β”‚
        β–Ό
Worker
        β”‚
        β”œβ”€β”€ Fetch repository snapshot
        β”œβ”€β”€ Analyze diff
        β”œβ”€β”€ Parse symbols
        β”œβ”€β”€ Build change graph
        β”œβ”€β”€ Collect evidence
        β”œβ”€β”€ Analyze impact
        └── Persist claims
                β”‚
                β–Ό
        Explanation Packet
                β”‚
                β–Ό
           AI Provider
                β”‚
                β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                β”‚               β”‚
                β–Ό               β–Ό
             Ollama           OpenAI
             Local            Production
                β”‚               β”‚
                β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜
                        β–Ό
                  Explanation
                        β”‚
                        β–Ό
                   PostgreSQL
                    /       \
                   /         \
                  β–Ό           β–Ό
             React UI     GitHub API
                              β”‚
                              β–Ό
                        PR Comment

PR Explain follows:

Deterministic analysis first. AI narration second.

The deterministic pipeline creates a structured representation of the change.

The AI receives a bounded explanation packet containing those facts.

This separation provides several benefits:

  • Better grounding
  • Lower risk of hallucinated files or functions
  • Repeatable analysis
  • Inspectable evidence
  • Local/private AI inference
  • Ability to change AI providers without changing the analysis pipeline
  • AI failures do not destroy deterministic analysis

The GitHub App is the entry point into PR Explain.

It receives Pull Request webhook events and gives PR Explain permission to read repository contents and update Pull Request comments.

Permission Access Purpose
Metadata Read Repository and installation metadata
Contents Read Read repository contents
Pull requests Write Create/update PR explanation comments

PR Explain does not require GitHub Checks permissions and does not submit a Pull Request review score.

You need to create a GitHub App before PR Explain can receive Pull Request events.

GitHub's official documentation:

GitHub Apps Quickstart

Go to:

GitHub
  β†’ Settings
  β†’ Developer settings
  β†’ GitHub Apps
  β†’ New GitHub App

For an organization-owned application:

Organization
  β†’ Settings
  β†’ Developer settings
  β†’ GitHub Apps
  β†’ New GitHub App

Use:

GitHub App name: PR Explain

Configure the homepage URL to point to your deployed application or repository.

Enable:

Active: Yes

Set the webhook URL to:

https://<your-public-host>/api/webhooks/github

For local development, GitHub cannot directly reach localhost.

Use a tunnel such as Cloudflare Tunnel:

cloudflared tunnel --url http://localhost:8000

If the tunnel provides:

https://example.trycloudflare.com

configure:

https://example.trycloudflare.com/api/webhooks/github

as the GitHub App webhook URL.

Only the FastAPI API needs to be exposed.

Do not expose Ollama publicly.

Generate a strong random secret and configure the same value in:

GITHUB_WEBHOOK_SECRET=your-secret

The webhook secret is used to validate that incoming webhook requests originate from GitHub.

Never commit the webhook secret to Git.

Subscribe to:

  • installation
  • installation_repositories
  • pull_request

For Pull Requests, PR Explain handles:

  • opened
  • reopened
  • synchronize
  • closed

The closed event is received but does not trigger analysis.

From the GitHub App settings:

Private keys
  β†’ Generate a private key

GitHub will download a .pem file.

For example:

pr-explain.private-key.pem

Keep this file secure.

GitHub documentation:

Managing private keys for GitHub Apps

Configure:

GITHUB_APP_ID=123456

GITHUB_APP_PRIVATE_KEY_FILE=/absolute/path/to/pr-explain.private-key.pem

GITHUB_WEBHOOK_SECRET=your-webhook-secret

When using Docker Compose, the private key is mounted into the containers as:

/run/secrets/github-app.pem

The application reads the private key from the mounted file.

Keep this empty when using the file-based configuration:

GITHUB_APP_PRIVATE_KEY=

After creating the GitHub App:

  1. Open the GitHub App settings.
  2. Select Install App .
  3. Select the GitHub account or organization.
  4. Choose the repositories where PR Explain should operate.
  5. Complete the installation.

For security, use Only select repositories if PR Explain should only operate on specific repositories.

Install:

  • Docker Desktop
  • Git
  • GitHub account
  • GitHub App
  • Cloudflare Tunnel or another webhook tunnel

Docker Compose runs the local application stack.

The local stack contains:

PostgreSQL
Ollama
Ollama model down
FastAPI API
Background worker
React frontend
git clone https://github.com/rajatrao/PR_explain.git

cd PR_explain

Create your environment file:

cp .env.example .env

At minimum, configure:

GITHUB_APP_ID=YOUR_APP_ID

GITHUB_APP_PRIVATE_KEY_FILE=/absolute/path/to/pr-explain.private-key.pem

GITHUB_WEBHOOK_SECRET=YOUR_WEBHOOK_SECRET

Local development uses Ollama running in Docker.

The default provider is:

LLM_PROVIDER=ollama

The default configuration is:

LLM_PROVIDER=ollama

OLLAMA_BASE_URL=http://127.0.0.1:11434

OLLAMA_MODEL=qwen3-coder:30b

OLLAMA_TIMEOUT_MS=180000

The first Docker Compose startup downloads the configured model into a persistent Ollama volume.

This allows the entire AI workflow to run locally without sending the explanation packet to a cloud AI provider.

Run:

docker compose up

The local services are:

Service Address
React frontend http://localhost:5173
FastAPI API http://localhost:8000
Ollama http://localhost:11434
PostgreSQL localhost:5432

The first startup may take some time because the Ollama model needs to be downloaded.

Start a local webhook tunnel:

cloudflared tunnel --url http://localhost:8000

Then configure the GitHub App webhook:

https://<tunnel-host>/api/webhooks/github

For example:

https://example.trycloudflare.com/api/webhooks/github

Again:

Do not expose port 11434 publicly.

The webhook tunnel should only point to the FastAPI API.

Mermaid flowchart: GitHub, Cloudflare Tunnel, FastAPI API, ("PostgreSQL"), Background Worker, Ollama Docker, qwen3-coder:30b, React UI

The important architectural property is:

GitHub
   β”‚
   β–Ό
FastAPI
   β”‚
   β–Ό
Worker
   β”‚
   β–Ό
Ollama

The FastAPI API does not directly perform model inference.

The worker owns the long-running analysis and AI interaction.

This keeps webhook processing fast and prevents model inference from blocking HTTP requests.

Production deployments can use a public AI model such as OpenAI instead of running Ollama.

The provider is selected through configuration.

LLM_PROVIDER=ollama

Flow:

Worker
   β”‚
   β–Ό
Ollama
   β”‚
   β–Ό
Local AI Model
LLM_PROVIDER=openai

Flow:

Worker
   β”‚
   β–Ό
OpenAI API
   β”‚
   β–Ό
Cloud AI Model

No application code changes are required to switch between these configurations.

For production, configure:

LLM_PROVIDER=openai

LLM_BASE_URL=https://api.openai.com/v1

LLM_API_KEY=your-openai-api-key

LLM_MODEL=your-model-name

For example:

LLM_PROVIDER=openai
LLM_BASE_URL=https://api.openai.com/v1
LLM_API_KEY=...
LLM_MODEL=...

OpenAI API documentation:

OpenAI API Quickstart

Store the API key using your deployment platform's secret manager.

Do not commit:

LLM_API_KEY=...

to Git.

Local Development Production
Provider Ollama OpenAI
Runtime Docker Cloud API
Model qwen3-coder:30b Configured cloud model
Network Local Internet
API key Not required Required
Ollama Required Not required
Application code Same Same
Configuration LLM_PROVIDER=ollama LLM_PROVIDER=openai

The AI provider is an explicit configuration choice.

There is no automatic fallback between providers.

For example:

LLM_PROVIDER=openai

does not silently fall back to Ollama.

Likewise:

LLM_PROVIDER=ollama

does not automatically send data to a public AI provider.

This makes the data-flow and privacy decision explicit.

A typical production deployment looks like:

Mermaid flowchart: GitHub, GitHub App, HTTPS / Load Balancer, FastAPI API, ("PostgreSQL"), Background Worker, OpenAI API, React Web App, Pull Request Comment

The production deployment can therefore be thought of as:

                        GitHub
                           β”‚
                           β”‚ Webhook
                           β–Ό
                  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                  β”‚   FastAPI API   β”‚
                  β”‚                 β”‚
                  β”‚ Webhooks / API  β”‚
                  β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                           β”‚
                           β–Ό
                  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                  β”‚   PostgreSQL    β”‚
                  β”‚                 β”‚
                  β”‚ Jobs / Analysis β”‚
                  β”‚ Claims / Output β”‚
                  β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                           β”‚
                           β–Ό
                  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                  β”‚ Background      β”‚
                  β”‚ Worker          β”‚
                  β”‚                 β”‚
                  β”‚ Analysis + AI   β”‚
                  β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                           β”‚
                    Explanation
                       Packet
                           β”‚
                           β–Ό
                  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                  β”‚    OpenAI API   β”‚
                  β”‚                 β”‚
                  β”‚   AI Model      β”‚
                  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

One of the most important properties of PR Explain is making the AI data path explicit.

GitHub
   β”‚
   β–Ό
Self-hosted API
   β”‚
   β–Ό
Self-hosted Worker
   β”‚
   β”œβ”€β”€ Repository snapshot
   β”œβ”€β”€ Pull Request diff
   β”œβ”€β”€ Symbols
   β”œβ”€β”€ Evidence
   └── Explanation packet
             β”‚
             β–Ό
       Local Ollama

In this mode, AI inference is performed locally on infrastructure you control.

GitHub
   β”‚
   β–Ό
Self-hosted API
   β”‚
   β–Ό
Self-hosted Worker
   β”‚
   └── Explanation packet
             β”‚
             β–Ό
        OpenAI API

When:

LLM_PROVIDER=openai

the configured explanation packet is sent to the cloud AI provider.

This is an explicit configuration decision.

AI inference and repository analysis can take significantly longer than a normal HTTP request.

The webhook path therefore does not perform the complete analysis synchronously.

Instead:

GitHub
   β”‚
   β–Ό
Webhook
   β”‚
   β–Ό
FastAPI
   β”‚
   β–Ό
Create Job
   β”‚
   β–Ό
Return

The worker then performs:

Job
 β”‚
 β”œβ”€β”€ Repository snapshot
 β”œβ”€β”€ Diff analysis
 β”œβ”€β”€ Symbol analysis
 β”œβ”€β”€ Change graph
 β”œβ”€β”€ Evidence
 β”œβ”€β”€ Impact
 β”œβ”€β”€ Explanation packet
 β”œβ”€β”€ AI inference
 └── GitHub comment

This provides:

  • Fast webhook responses
  • Retryable background jobs
  • Better failure isolation
  • Long-running AI inference outside the HTTP request
  • Separation between API and processing workloads

The current processing pipeline is:

snapshot_fetch
      β”‚
      β–Ό
diff_analysis
      β”‚
      β–Ό
symbol_analysis
      β”‚
      β–Ό
change_graph
      β”‚
      β–Ό
evidence
      β”‚
      β–Ό
impact
      β”‚
      β–Ό
claims_persisted
      β”‚
      β–Ό
explanation_packet_persisted
      β”‚
      β–Ό
explanation
      β”‚
      β–Ό
comment

The deterministic analysis stage produces facts about the Pull Request.

Examples include:

src/payment/service.py
src/payment/repository.py
tests/payment/test_service.py
PaymentService.process_payment
PaymentRepository.create
PaymentEventPublisher.publish
PaymentService.process_payment
        β”‚
        β”œβ”€β”€ calls β†’ PaymentRepository.create
        β”‚
        └── calls β†’ PaymentEventPublisher.publish

The analysis can associate claims with the relevant source or diff evidence.

Files and symbols outside the direct diff can be identified when they are relevant to the change.

The AI model does not receive an unrestricted repository and is not expected to independently discover the entire change.

Instead, the worker constructs a bounded explanation packet.

Conceptually:

Explanation Packet
β”œβ”€β”€ Pull Request metadata
β”œβ”€β”€ Changed files
β”œβ”€β”€ Changed symbols
β”œβ”€β”€ Relationships
β”œβ”€β”€ Evidence
β”œβ”€β”€ Impact
β”œβ”€β”€ Claims
└── Relevant context

The packet is intentionally bounded to prevent unnecessarily large model requests.

The AI model takes the explanation packet and turns it into human-readable language.

Conceptually:

Change Graph
     +
Evidence
     +
Impact
     +
Claims
     β”‚
     β–Ό
Explanation Packet
     β”‚
     β–Ό
AI Model
     β”‚
     β–Ό
Human-readable Explanation

The model should explain the supplied facts rather than invent unsupported relationships.

PR Explain separates:

analysis_status
explanation_status
comment_status

This is important because deterministic analysis and AI narration are independent stages.

For example:

GitHub PR
    β”‚
    β–Ό
Analysis
    β”‚
    β–Ό
Claims Stored
    β”‚
    β–Ό
AI Explanation
    β”‚
    β”œβ”€β”€ SUCCESS
    β”‚
    └── FAILURE

If the AI provider fails:

  • Deterministic analysis is not discarded.
  • Claims remain stored.
  • Files and symbols remain available.
  • Explanation can be retried.
  • The Pull Request comment is not posted until explanation succeeds.

Similarly, if the GitHub comment update fails, the stored analysis and explanation remain available in the application.

PR Explain maintains one conversation-style explanation comment per Pull Request.

When a Pull Request receives a new commit:

New Commit
    β”‚
    β–Ό
New HEAD SHA
    β”‚
    β–Ό
New Analysis
    β”‚
    β–Ό
New Explanation
    β”‚
    β–Ό
Existing PR Comment Updated

This avoids creating a new comment for every commit.

The application can also compare claim sets across different Pull Request head SHAs to expose revision deltas.

The React frontend provides two primary views.

The Explain view provides the high-level change story and diagram.

It answers:

What changed and how does this change affect the system?

The Details view exposes the underlying evidence:

  • Changed files
  • Symbols
  • Call relationships
  • Line-level evidence
  • Tests
  • Relevant files outside the diff
  • API facts
  • Unknown facts
  • Analysis status
  • Explanation status

Both views are backed by the same stored analysis.

PR_explain/
β”œβ”€β”€ backend/
β”‚   └── app/
β”‚       β”œβ”€β”€ api/
β”‚       β”œβ”€β”€ analysis/
β”‚       β”œβ”€β”€ llm/
β”‚       β”œβ”€β”€ worker/
β”‚       └── ...
β”‚
β”œβ”€β”€ frontend/
β”‚   └── ...
β”‚
β”œβ”€β”€ fixtures/
β”‚   └── bench/
β”‚
β”œβ”€β”€ .env.example
β”œβ”€β”€ docker-compose.yml
β”œβ”€β”€ README.md
└── .gitignore

Main runtime components:

Component Responsibility
backend API, GitHub integration, analysis and worker
frontend React web application
postgres Persistent application data
worker Background analysis and AI explanation
ollama Local AI inference
ollama-pull Downloads the configured Ollama model
fixtures Test and benchmark fixtures
GITHUB_APP_ID=
GITHUB_APP_PRIVATE_KEY_FILE=
GITHUB_WEBHOOK_SECRET=
GITHUB_API_URL=https://api.github.com
LLM_PROVIDER=ollama

OLLAMA_BASE_URL=http://127.0.0.1:11434

OLLAMA_MODEL=qwen3-coder:30b

OLLAMA_TIMEOUT_MS=180000
LLM_PROVIDER=openai

LLM_BASE_URL=https://api.openai.com/v1

LLM_API_KEY=

LLM_MODEL=
DATABASE_URL=postgresql+psycopg://pr_explain:pr_explain@localhost:5432/pr_explain

POSTGRES_USER=pr_explain
POSTGRES_PASSWORD=pr_explain
POSTGRES_DB=pr_explain
APP_BASE_URL=http://localhost:5173

CORS_ORIGINS=http://localhost:5173
EXPLANATION_PACKET_CHAR_BUDGET=32000

FANOUT_CAP=50

MAX_CHANGED_SYMBOLS=80

Use .env.example as the source of truth for the current supported configuration.

The test suite can run without Ollama or GitHub.

cd backend

python3 -m venv .venv

source .venv/bin/activate

pip install -e ".[dev]"

pytest

Tests cover areas including:

  • OAuth fixture claims
  • Citation validation
  • Worker failure behavior
  • Comment rendering

The test suite does not need to download an AI model or contact GitHub.

For lightweight local development:

cd backend

DATABASE_URL=sqlite:///./dev.db \
PYTHONPATH=. \
python -m app.seed

Start FastAPI:

DATABASE_URL=sqlite:///./dev.db \
PYTHONPATH=. \
uvicorn app.api:app --port 8000

In another terminal:

cd frontend

npm install

npm run dev

Then open the URL printed by the frontend development server.

PR Explain includes a model benchmark for testing different AI providers and models against frozen explanation packets.

Run:

python -m app.llm.bench

The benchmark produces a local JSON report covering areas such as:

  • Grounding
  • Structure
  • Latency
  • Process memory

The benchmark is intended to evaluate the model/provider configuration.

It is not a Pull Request quality score.

Do not commit:

.env
*.pem
GitHub App private keys
GitHub webhook secrets
LLM API keys
Database passwords

The GitHub App private key grants the application authentication capabilities as the GitHub App.

Keep it outside source control and inject it into the application using a secure file or secret-management mechanism.

For local development, Ollama is bound to:

127.0.0.1:11434

Do not expose Ollama through your GitHub webhook tunnel.

Only the FastAPI API needs to be publicly reachable:

Internet
    β”‚
    β–Ό
FastAPI :8000

not:

Internet
    β”‚
    β–Ό
Ollama :11434

Use your deployment platform's secret manager for:

GITHUB_APP_PRIVATE_KEY
GITHUB_WEBHOOK_SECRET
LLM_API_KEY
POSTGRES_PASSWORD

Do not store production secrets in the Git repository.

Before deploying PR Explain:

  • Create the GitHub App
  • Configure Metadata β†’ Read
  • Configure Contents β†’ Read
  • Configure Pull requests β†’ Write
  • Enable installation events
  • Enable installation repository events
  • Enable Pull Request events
  • Generate GitHub App private key
  • Store the private key securely
  • Configure GITHUB_APP_ID
  • Configure GITHUB_WEBHOOK_SECRET
  • Install the GitHub App on the required repositories
  • Deploy FastAPI with HTTPS
  • Configure the GitHub webhook URL
  • Deploy PostgreSQL
  • Deploy the background worker
  • Configure LLM_PROVIDER=openai
  • Configure LLM_BASE_URL
  • Configure LLM_API_KEY
  • Configure LLM_MODEL
  • Configure frontend production API origin
  • Configure CORS
  • Configure persistent database storage
  • Configure application logging and monitoring
  • Test a Pull Request from webhook through analysis to GitHub comment
  • Verify that Ollama is not publicly exposed
  • Verify that secrets are not present in logs

For production, use a real HTTPS server/application endpoint rather than a development webhook tunnel.

Suppose a developer opens:

PR #42

Add payment event publishing

The Pull Request modifies:

src/payment/service.py
src/payment/events.py
tests/payment/test_service.py

PR Explain receives:

GitHub Webhook
      β”‚
      β–Ό
FastAPI
      β”‚
      β–Ό
Background Worker

The worker analyzes the repository:

PaymentService.process_payment()
          β”‚
          β”œβ”€β”€ PaymentRepository.create()
          β”‚
          └── PaymentEventPublisher.publish()

It collects:

Files
Symbols
Relationships
Evidence
Impact
Claims

It creates:

Explanation Packet

The configured AI provider then receives the packet.

Explanation Packet
       β”‚
       β–Ό
Ollama
       β”‚
       β–Ό
Local Model
Explanation Packet
       β”‚
       β–Ό
OpenAI
       β”‚
       β–Ό
Cloud Model

The generated explanation is stored and posted to GitHub:

Worker
   β”‚
   β”œβ”€β”€ PostgreSQL
   β”‚
   └── GitHub API
          β”‚
          β–Ό
     PR #42 Comment

Like SQL EXPLAIN, PR Explain first produces a structured representation of what is happening.

The AI then explains that representation.

The system determines what changed before generating a natural-language explanation.

The model is a narrator over deterministic analysis.

Developers can run the complete AI workflow locally using Docker and Ollama.

No cloud AI API is required for local inference.

Production can use OpenAI or another compatible provider through configuration without changing the core analysis pipeline.

Switching from:

LLM_PROVIDER=ollama

to:

LLM_PROVIDER=openai

is an explicit decision to move AI inference from local infrastructure to a cloud provider.

Analysis, explanation, and GitHub commenting are separate stages.

A model failure should not destroy deterministic analysis.

The GitHub App requests only the repository permissions required by PR Explain.

If you remember only one thing about PR Explain, remember this:

                 SQL
                  β”‚
                  β–Ό
          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
          β”‚    EXPLAIN    β”‚
          β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜
                  β”‚
                  β–Ό
          Execution Plan
                  β”‚
                  β–Ό
         Human Understanding

                 Code
                  β”‚
                  β–Ό
          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
          β”‚  PR EXPLAIN   β”‚
          β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜
                  β”‚
                  β–Ό
       Change Graph + Evidence
                  β”‚
                  β–Ό
             AI Model
                  β”‚
                  β–Ό
         Human Understanding

PR Explain is EXPLAIN for Pull Requests.

It doesn't just ask an AI:

"What does this PR do?"

It first asks the codebase:

"What actually changed, what does it connect to, and what evidence supports that?"

Then it asks the AI:

"Now explain those facts to a human."

  • Support for scalable async processing of PR explain request
  • Improve explain notes to give more in-depth understanding of changes
  • Add more support for overall review experience

MIT β€” for hackathon / research use.

── more in #ai-tools 4 stories Β· sorted by recency
── more on @pr explain 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain β€” perfect for shipping the agent you just read about.

$git push zahid main
β†’ Live at https://your-agent.zahid.host βœ“
Get free account β†’ Pricing
from €0/mo Β· no card required
LIVE [news/what-if-pull-request…] indexed:0 read:17min 2026-10-06 Β· β€”