A single vulnerability finding from a gap-fill LLM call.
| 53 | |
| 54 | |
| 55 | class GapFillFinding(BaseModel): |
| 56 | """A single vulnerability finding from a gap-fill LLM call.""" |
| 57 | |
| 58 | rule_id: str = Field(description="Identifier matching one of the gap-fill rule IDs") |
| 59 | message: str = Field(description="Short description of the finding") |
| 60 | severity: Literal["LOW", "MEDIUM", "HIGH", "CRITICAL"] = Field( |
| 61 | description="Severity level" |
| 62 | ) |
| 63 | confidence: float = Field( |
| 64 | ge=0.0, le=1.0, default=0.7, description="Confidence score (0.0-1.0)" |
| 65 | ) |
| 66 | explanation: str = Field( |
| 67 | default="", description="Why this is dangerous (2-3 sentences)" |
| 68 | ) |
| 69 | remediation: str = Field( |
| 70 | default="", description="Actionable steps to fix the issue" |
| 71 | ) |
| 72 | |
| 73 | def to_finding(self, file: str) -> Finding: |
| 74 | """Convert to a :class:`~skillspector.models.Finding` for the report.""" |
| 75 | return Finding( |
| 76 | rule_id=self.rule_id, |
| 77 | message=self.message, |
| 78 | severity=self.severity, |
| 79 | confidence=self.confidence, |
| 80 | file=file, |
| 81 | category="Security", |
| 82 | explanation=self.explanation, |
| 83 | remediation=self.remediation, |
| 84 | ) |
| 85 | |
| 86 | |
| 87 | class GapFillResult(BaseModel): |
no outgoing calls