get_pr_impact β
Full risk assessment for a diff in one call. Walks every changed file, maps them to symbols, runs get_blast_radius on each, and layers on co-change history to surface files that historically change together but are missing from this PR.
Single-call convenience
This replaces running get_changed_symbols plus per-symbol get_blast_radius plus a history lookup. Use it before every merge.
Parameters β
| Name | Type | Required | Description |
|---|---|---|---|
since | string | no | Git ref to diff against (default "HEAD~1") |
maxFiles | integer | no | Cap on changed files analysed (default 50) |
confidence | "confirmed" | "likely" | "potential" | no | Restrict blast radius results to a single tier |
since accepts anything git diff accepts β a branch name (main), a tag, or a commit hash.
Example β
Review the last commit:
{}Review a feature branch against main:
{ "since": "main" }Review a specific commit range, confirmed impacts only:
{ "since": "abc123", "confidence": "confirmed", "maxFiles": 20 }Response β
{
"since": "HEAD~1",
"changedFiles": 3,
"changedSymbols": 7,
"totalImpact": 42,
"riskLevel": "high",
"files": [
{
"file": "packages/cli/src/core/graph/graph.ts",
"symbols": [
{
"symbolId": "packages/cli/src/core/graph/graph.ts::Graph::class",
"name": "Graph",
"kind": "class",
"blast": {
"impactScore": 31,
"confirmedCount": 8,
"likelyCount": 15,
"potentialCount": 8,
"riskScore": 0.88,
"topImpacted": [ /* up to 10 highest-risk dependents */ ]
}
}
],
"coChangedWith": [
"packages/cli/src/core/graph/graph-builder.ts",
"packages/cli/src/adapters/storage/sqlite.ts"
]
}
],
"summary": {
"confirmedTotal": 12,
"likelyTotal": 21,
"potentialTotal": 9,
"highRiskSymbols": [
"packages/cli/src/core/graph/graph.ts::Graph::class"
]
},
"boundaryViolations": {
"confidence": "medium",
"snapshotsAvailable": 4,
"violations": [
{
"from": { "symbolId": ".../CheckoutFlow::class", "communityId": 1, "label": "Billing" },
"to": { "symbolId": ".../UserPermissions::class", "communityId": 3, "label": "Auth" },
"edgeKind": "calls",
"historicalEdgesBetweenClusters": 0,
"severity": "high"
}
]
},
"clustersAffected": [
{ "id": 1, "label": "Billing", "symbolCount": 5 },
{ "id": 3, "label": "Auth", "symbolCount": 1 }
],
"_meta": { "totalItems": 3, "returnedItems": 3, "truncated": false }
}If the diff is empty:
{ "since": "HEAD~1", "changedFiles": 0, "changedSymbols": 0, "totalImpact": 0, "riskLevel": "low", "files": [], "summary": { "confirmedTotal": 0, "likelyTotal": 0, "potentialTotal": 0, "highRiskSymbols": [] } }Reading the verdict β
riskLevelβhighif any changed symbol hasriskScore > 0.7,mediumabove0.3, elselow. Use it as the top-line gate for review depth.summary.highRiskSymbolsβ the symbols most likely to break something. Review these first.files[].coChangedWithβ files that historically change together with this one but are not in the current diff. A strong signal that the PR may be incomplete.boundaryViolations.violations[](v0.8) β edges introduced by this PR between clusters that had no edges between them historically.severity: "high"+historicalEdgesBetweenClusters: 0is a first-ever layer crossing.clustersAffected[](v0.8) β distinct clusters the PR touches. A PR spanning 3+ clusters is usually a cross-team change.
Killer example: the first-ever cluster crossing β
A PR wires a direct call from CheckoutFlow (Billing cluster) to UserPermissions (Auth cluster). Typecheck passes. Tests pass. riskLevel from blast radius alone may even come back low β the affected set is tiny.
But the last 10 snapshots show zero edges between these two clusters. A senior reviewer would ask "why is Billing reaching into Auth internals?" Ctxo now hands that exact question to the AI reviewer before a human ever sees the PR:
"boundaryViolations": {
"violations": [{
"from": { "label": "Billing" },
"to": { "label": "Auth" },
"historicalEdgesBetweenClusters": 0,
"severity": "high"
}]
}This is architectural review from git history β no competitor MCP server has it.
When to use β
- PR review and pre-merge sanity check
- CI gate on high-risk changes (parse
riskLevel === "high"orboundaryViolations.violations.length > 0) - "Did I forget a file?" check via
coChangedWith - "Should this span multiple teams?" check via
clustersAffected
Related tools β
get_blast_radiusβ per-symbol deep diveget_changed_symbolsβ just the symbol list, no blast radiusget_why_contextβ follow up on any high-risk symbol to read its history