How the PR Summary Step in no-mistakes Performs Risk Assessment: A Deep Dive into the Code
The PR summary step in no-mistakes performs risk assessment by extracting RiskLevel and RiskRationale fields from the Review step's findings, mapping severity levels to visual emojis (✅, ⚠️, 🚨), and formatting a concise risk line that appears in the pull request description.
The no-mistakes repository automates code review pipelines by analyzing diffs and surfacing potential issues directly in pull requests. At the heart of this system lies the PR summary step, which transforms raw pipeline results into human-readable markdown while performing critical risk assessment. This article examines the Go implementation in internal/pipeline/steps/prsummary.go to show exactly how the system determines whether code changes introduce low, medium, or high risk.
Extracting Risk Data from the Review Step
The risk assessment logic begins in the extractRiskLine function located at lines 200-242 of internal/pipeline/steps/prsummary.go. This function iterates through the slice of *db.StepResult to locate the specific Review step, as this is the only step that carries risk data according to the no-mistakes architecture.
The function first attempts to parse the step's own FindingsJSON field:
var finalFindings *types.Findings
src := finalFindings
if src == nil && !hasUnreadableFinal {
stepRounds := rounds[sr.ID]
if len(stepRounds) > 0 {
last := stepRounds[len(stepRounds)-1]
if last.FindingsJSON != nil {
if f, err := types.ParseFindingsJSON(*last.FindingsJSON); err == nil {
src = &f
}
}
}
}
If the step's FindingsJSON is missing or unreadable, the code automatically falls back to the last round's findings using stepRounds[len(stepRounds)-1]. This fallback mechanism ensures that risk assessment persists even when the final step execution fails to write its own findings.
Mapping Risk Levels to Visual Indicators
Once the system locates valid findings containing a RiskLevel string, it translates the severity into visual cues using the riskEmoji function at lines 452-462:
func riskEmoji(level string) string {
switch level {
case "low": return "✅"
case "medium": return "⚠️"
case "high": return "🚨"
default: return "ℹ️"
}
}
The capitalizeRisk helper converts the raw level string to a properly capitalized label ("Low", "Medium", or "High"). The final risk line construction checks for an optional RiskRationale field:
if src.RiskRationale != "" {
return fmt.Sprintf("%s %s: %s", emoji, label, src.RiskRationale)
}
return fmt.Sprintf("%s %s", emoji, label)
This produces outputs such as ✅ Low, ⚠️ Medium: may overwrite production DB, or 🚨 High.
Handling Risk Without Explicit Findings
Inside buildStepEntry (lines 690-720), the PR summary step implements special handling for cases where the Review step reports elevated risk but contains no concrete finding items. When riskLevel equals "medium" or "high" and hadAnyFindings is false, the system renders a warning line:
if sr.StepName == types.StepReview && (riskLevel == "medium" || riskLevel == "high") && !hadAnyFindings {
return buildDetail(fmt.Sprintf("%s **%s** - %s risk", riskEmoji(riskLevel), name, riskLevel))
}
This ensures that reviewers see risk indicators even when the AI agent flags general concerns without specific code locations.
Integrating Risk Assessment into PR Descriptions
The BuildPipelineSummary function (lines 38-72) orchestrates the final assembly by calling extractRiskLine and returning both the complete markdown and the isolated risk string:
riskLine := extractRiskLine(steps, rounds)
return b.String(), riskLine
According to the source code in internal/pipeline/steps/pr.go at line 222, the calling code stores this riskLine alongside the pipeline markdown, which later appears in the PR description header. This integration allows the risk assessment to surface prominently at the top of every pull request.
Practical Implementation Example
The following simplified Go code demonstrates how to generate a PR summary with risk assessment:
package main
import (
"fmt"
"github.com/kunchenguid/no-mistakes/internal/db"
"github.com/kunchenguid/no-mistakes/internal/pipeline/steps"
)
func main() {
// Assume steps and rounds are populated from the daemon after a run
var stepResults []*db.StepResult
var rounds map[string][]*db.StepRound
// ... populate stepResults and rounds ...
md, risk := steps.BuildPipelineSummary(stepResults, rounds)
fmt.Println("=== Pipeline Markdown ===")
fmt.Println(md)
fmt.Println("\n=== Risk Line ===")
fmt.Println(risk) // Example: "🚨 High: possible data loss"
}
Summary
- The PR summary step extracts risk data exclusively from the Review step findings in
internal/pipeline/steps/prsummary.go. - A fallback mechanism checks the last round's findings when the step's own FindingsJSON is unavailable.
- The
riskEmojifunction maps severity levels to ✅, ⚠️, and 🚨 for immediate visual recognition. - The final risk line combines the emoji, capitalized severity label, and optional
RiskRationaletext. - Integration occurs through
BuildPipelineSummary, consumed byinternal/pipeline/steps/pr.goto display risk in PR descriptions.
Frequently Asked Questions
Which pipeline step provides the risk data for the PR summary?
Only the Review step provides risk data. The extractRiskLine function explicitly filters for types.StepReview and ignores all other steps in the pipeline, as the Review step is responsible for analyzing the diff and assigning risk levels.
What happens if the Review step's FindingsJSON is missing or corrupted?
The system implements a fallback chain: if the step's FindingsJSON is nil or fails to parse, extractRiskLine retrieves the last round from the rounds map using stepRounds[len(stepRounds)-1] and attempts to parse that round's FindingsJSON instead.
How does the system handle medium or high risk when no specific findings are reported?
Inside buildStepEntry (lines 690-720), when the risk level is "medium" or "high" but hadAnyFindings is false, the function renders a special warning line format: ⚠️ **Review** - medium risk or 🚨 **Review** - high risk, ensuring reviewers see the risk flag even without specific code locations.
Where is the risk line ultimately displayed in the pull request?
The risk line appears in the PR description header. The BuildPipelineSummary function returns the risk string to its caller in internal/pipeline/steps/pr.go (line 222), which stores it alongside the pipeline markdown for display at the top of the pull request description.
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 →