Skip to content

Findings & Severity

Findings capture specific issues discovered during evaluation, with severity levels following InfoSec conventions.

Finding Structure

type Finding struct {
    ID             string   `json:"id,omitempty"`
    Severity       Severity `json:"severity"`
    Category       string   `json:"category"`
    Title          string   `json:"title"`
    Description    string   `json:"description,omitempty"`
    Location       string   `json:"location,omitempty"`
    Recommendation string   `json:"recommendation,omitempty"`
    References     []string `json:"references,omitempty"`
}

Severity Levels

Severity Icon Blocking Description
Critical 🔴 Yes Must fix before approval; security vulnerabilities, data loss risks
High 🔴 Yes Must fix before approval; major functionality gaps
Medium 🟡 No Should fix; tracked issues that don't block
Low 🟢 No Nice to fix; minor improvements
Info No Informational; observations, suggestions

Creating Findings

// Critical finding - blocks approval
report.AddFinding(evaluation.Finding{
    Severity:       evaluation.SeverityCritical,
    Category:       "security",
    Title:          "SQL injection vulnerability",
    Description:    "User input is concatenated directly into SQL query",
    Location:       "src/db/queries.go:142",
    Recommendation: "Use parameterized queries",
    References:     []string{"OWASP-A03:2021"},
})

// Medium finding - tracked but doesn't block
report.AddFinding(evaluation.Finding{
    Severity:       evaluation.SeverityMedium,
    Category:       "documentation",
    Title:          "Missing API documentation",
    Description:    "Public endpoints lack OpenAPI annotations",
    Recommendation: "Add swagger comments to all public handlers",
})

// Info finding - observation
report.AddFinding(evaluation.Finding{
    Severity:    evaluation.SeverityInfo,
    Category:    "style",
    Title:       "Consider using table-driven tests",
    Description: "Test file has repetitive test cases",
})

Finding Counts

The decision tracks finding counts by severity:

type FindingCounts struct {
    Critical int `json:"critical"`
    High     int `json:"high"`
    Medium   int `json:"medium"`
    Low      int `json:"low"`
    Info     int `json:"info"`
    Total    int `json:"total"`
}

// BlockingCount returns critical + high
func (fc FindingCounts) BlockingCount() int {
    return fc.Critical + fc.High
}

Usage

counts := report.Decision.FindingCounts

if counts.BlockingCount() > 0 {
    fmt.Printf("❌ %d blocking issues found\n", counts.BlockingCount())
}

fmt.Printf("Findings: %d critical, %d high, %d medium, %d low\n",
    counts.Critical, counts.High, counts.Medium, counts.Low)

Severity Methods

severity := evaluation.SeverityHigh

severity.Icon()        // "🔴"
severity.IsBlocking()  // true
severity.Priority()    // 2 (lower = more severe)
Severity Icon IsBlocking Priority
Critical 🔴 true 1
High 🔴 true 2
Medium 🟡 false 3
Low 🟢 false 4
Info false 5

Grouping Findings

Findings can be grouped by category or severity for display:

// Group by category
byCategory := make(map[string][]Finding)
for _, f := range report.Findings {
    byCategory[f.Category] = append(byCategory[f.Category], f)
}

// Group by severity
bySeverity := make(map[Severity][]Finding)
for _, f := range report.Findings {
    bySeverity[f.Severity] = append(bySeverity[f.Severity], f)
}

Best Practices

Writing Good Finding Titles

  • ✅ "Missing input validation on user ID parameter"
  • ❌ "Bad code"
  • ✅ "API rate limiting not implemented"
  • ❌ "Needs work"

Writing Recommendations

  • Be specific and actionable
  • Reference standards when applicable
  • Provide code examples if helpful
Finding{
    Title:          "Passwords stored in plaintext",
    Recommendation: "Use bcrypt with cost factor ≥12. See OWASP Password Storage Cheat Sheet.",
}

Using Location

Include file paths and line numbers when available:

Finding{
    Location: "src/auth/handler.go:89",  // File:line
    Location: "Section 3.2",              // Document section
    Location: "API: POST /users",         // Endpoint
}

Next Steps