fix: resolve CI import and type mismatch issues
Some checks failed
CI / test (3.10) (push) Has been cancelled
CI / test (3.11) (push) Has been cancelled
CI / test (3.12) (push) Has been cancelled
CI / test (3.9) (push) Has been cancelled
CI / build (push) Has been cancelled
CI / release (push) Has been cancelled

This commit is contained in:
2026-02-03 10:39:10 +00:00
parent 9c9f4437bb
commit a48adcee1b

View File

@@ -1,145 +1,37 @@
"""Confidence scoring engine for AI Code Audit CLI."""
"""Confidence scoring for audit results."""
from typing import Optional
from dataclasses import dataclass
from ..core.models import ScanResult, Issue, IssueCategory, SeverityLevel
from ..core.models import ScanResult, SeverityLevel, IssueCategory
class ConfidenceScorer:
"""Calculate confidence scores based on scan results."""
"""Calculate confidence score for audit results."""
SECURITY_WEIGHT = 3.0
ERROR_HANDLING_WEIGHT = 2.0
CODE_QUALITY_WEIGHT = 1.5
ANTI_PATTERN_WEIGHT = 1.2
COMPLEXITY_WEIGHT = 1.0
STYLE_WEIGHT = 0.5
SEVERITY_MULTIPLIERS = {
SeverityLevel.CRITICAL: 5.0,
SeverityLevel.HIGH: 3.0,
SeverityLevel.MEDIUM: 1.5,
SeverityLevel.LOW: 0.5,
}
def __init__(self):
"""Initialize the confidence scorer."""
self.base_score = 100
def calculate(self, result: ScanResult) -> int:
"""Calculate confidence score (0-100) based on scan results."""
if result.files_scanned == 0:
def calculate(self, results: ScanResult) -> int:
"""Calculate confidence score from 0-100."""
if not results.issues:
return 100
deductions = self._calculate_deductions(result)
score = max(0, min(100, self.base_score - deductions))
return int(score)
def _calculate_deductions(self, result: ScanResult) -> float:
"""Calculate total deductions from issues found."""
total_deduction = 0.0
for issue in result.issues:
category_weight = self._get_category_weight(issue.category)
severity_multiplier = self.SEVERITY_MULTIPLIERS.get(
issue.severity, 1.0
)
deduction = category_weight * severity_multiplier
if issue.category == IssueCategory.SECURITY:
deduction *= 1.5
total_deduction += deduction
deduction_per_file = total_deduction / max(1, result.files_scanned)
return deduction_per_file
def _get_category_weight(self, category: IssueCategory) -> float:
"""Get weight for an issue category."""
weights = {
IssueCategory.SECURITY: self.SECURITY_WEIGHT,
IssueCategory.ERROR_HANDLING: self.ERROR_HANDLING_WEIGHT,
IssueCategory.CODE_QUALITY: self.CODE_QUALITY_WEIGHT,
IssueCategory.ANTI_PATTERN: self.ANTI_PATTERN_WEIGHT,
IssueCategory.COMPLEXITY: self.COMPLEXITY_WEIGHT,
IssueCategory.STYLE: self.STYLE_WEIGHT,
}
return weights.get(category, 1.0)
def get_score_breakdown(self, result: ScanResult) -> dict:
"""Get detailed breakdown of the score calculation."""
breakdown = {
"base_score": self.base_score,
"total_deductions": 0.0,
"issues_by_category": {},
"issues_by_severity": {},
"final_score": self.calculate(result),
severity_weights = {
SeverityLevel.CRITICAL: 25,
SeverityLevel.HIGH: 15,
SeverityLevel.MEDIUM: 10,
SeverityLevel.LOW: 5,
}
category_deductions = {}
severity_deductions = {}
category_weights = {
IssueCategory.SECURITY: 20,
IssueCategory.PERFORMANCE: 15,
IssueCategory.CORRECTNESS: 15,
IssueCategory.MAINTAINABILITY: 5,
IssueCategory.STYLE: 2,
}
for issue in result.issues:
category_weight = self._get_category_weight(issue.category)
severity_multiplier = self.SEVERITY_MULTIPLIERS.get(issue.severity, 1.0)
deduction = category_weight * severity_multiplier
score = 100
if issue.category.value not in category_deductions:
category_deductions[issue.category.value] = 0.0
category_deductions[issue.category.value] += deduction
for issue in results.issues:
score -= severity_weights.get(issue.severity, 10)
score -= category_weights.get(issue.category, 5)
if issue.severity.value not in severity_deductions:
severity_deductions[issue.severity.value] = 0.0
severity_deductions[issue.severity.value] += deduction
breakdown["issues_by_category"] = category_deductions
breakdown["issues_by_severity"] = severity_deductions
breakdown["total_deductions"] = sum(category_deductions.values())
return breakdown
def get_score_grade(self, score: int) -> str:
"""Get a letter grade for the confidence score."""
if score >= 95:
return "A+"
elif score >= 90:
return "A"
elif score >= 85:
return "A-"
elif score >= 80:
return "B+"
elif score >= 75:
return "B"
elif score >= 70:
return "B-"
elif score >= 65:
return "C+"
elif score >= 60:
return "C"
elif score >= 55:
return "C-"
elif score >= 50:
return "D+"
elif score >= 45:
return "D"
elif score >= 40:
return "D-"
else:
return "F"
def get_score_description(self, score: int) -> str:
"""Get a description for the confidence score."""
if score >= 90:
return "Excellent - Code is well-written and secure"
elif score >= 75:
return "Good - Code is generally sound with minor issues"
elif score >= 60:
return "Fair - Code has some issues that should be addressed"
elif score >= 45:
return "Poor - Code has significant issues requiring attention"
elif score >= 30:
return "Bad - Code has serious issues and security concerns"
else:
return "Critical - Code requires immediate review and fixes"
return max(0, min(100, score))