What Is the Maximum Risk Score Computed by SkillSpector?
The maximum risk score computed by SkillSpector is 100, representing the ceiling of a clamped calculation that combines base vulnerability severity points with an optional executable-script multiplier.
NVIDIA's SkillSpector evaluates AI skill bundles for security vulnerabilities using a quantitative scoring algorithm. The risk assessment is performed by the private helper _compute_risk_score in src/skillspector/nodes/report.py, which aggregates findings, applies multipliers, and bounds the final result between 0 and 100.
How SkillSpector Calculates Risk Scores
The scoring algorithm follows a three-stage pipeline: base point accumulation, conditional multiplication, and hard ceiling enforcement.
Base Severity Point Values
Each security finding contributes a fixed point value based on its severity classification. The function iterates through findings at lines 81-92, applying these values:
- CRITICAL: 50 points
- HIGH: 25 points
- MEDIUM: 10 points
- LOW: 5 points
These values are summed to create a subtotal before any multipliers or clamping is applied.
Executable Script Multiplier
If the scanned skill bundle contains executable scripts (has_executable_scripts == True), the algorithm applies a 1.3× multiplier to the subtotal. As implemented in lines 93-95, the multiplication occurs before integer conversion:
# From src/skillspector/nodes/report.py (lines 93-95)
if has_executable_scripts:
score = int(score * 1.3)
The int() conversion truncates decimal values (rounds down), meaning a calculated value of 45.5 becomes 45.
Score Clamping and the Maximum Value
After applying the multiplier, the score is clamped to the inclusive range 0-100 using a standard min/max operation. This ensures that even bundles with extreme vulnerability counts cannot exceed the maximum risk score of 100. The clamping occurs immediately after the multiplier step, before severity band classification.
Severity Band Mapping
The final numeric score maps to semantic labels using the _RISK_SEVERITY_BANDS ordered list (lines 96-100):
- CRITICAL: ≥ 81 points
- HIGH: ≥ 51 points
- MEDIUM: ≥ 21 points
- LOW: < 21 points
Any score of 100 falls into the CRITICAL band, triggering the DO_NOT_INSTALL recommendation defined in _RISK_RECOMMENDATION (lines 55-60).
Implementation Details in report.py
The _compute_risk_score function signature accepts a list of Finding objects and a boolean flag indicating executable presence:
def _compute_risk_score(findings: List[Finding], has_executable_scripts: bool) -> Tuple[int, str, str]:
# Returns: (score: 0-100, severity_band: str, recommendation: str)
Key implementation locations in src/skillspector/nodes/report.py:
- Lines 81-92: Base point accumulation loop
- Lines 93-95: Executable multiplier and clamping to 0-100
- Lines 96-100: Severity band lookup against
_RISK_SEVERITY_BANDS - Line 101: Recommendation mapping via
_RISK_RECOMMENDATION
Practical Example: Computing Maximum Risk
To reach the maximum score of 100 without the executable multiplier requires accumulating at least 100 base points (e.g., two CRITICAL findings: 50 + 50 = 100).
With the executable multiplier active, the minimum base points needed to hit the 100 ceiling is 77, since 77 × 1.3 = 100.1 (truncated to 100):
from skillspector.nodes.report import _compute_risk_score
from skillspector.models import Finding
# Create two CRITICAL findings (50 pts each) and one HIGH (25)
# Base: 125 points
findings = [
Finding(rule_id="S001", severity="CRITICAL", message="Arbitrary code execution",
file="skill.py", start_line=1, end_line=10, confidence=0.95),
Finding(rule_id="S002", severity="CRITICAL", message="Unsafe deserialization",
file="utils.py", start_line=5, end_line=20, confidence=0.95),
Finding(rule_id="S003", severity="HIGH", message="Weak crypto",
file="crypto.py", start_line=30, end_line=35, confidence=0.90),
]
# With executable scripts present, multiplier applies
has_executable_scripts = True
score, severity, recommendation = _compute_risk_score(findings, has_executable_scripts)
print(f"Score: {score}") # → 100 (capped)
print(f"Severity: {severity}") # → CRITICAL
print(f"Recommendation: {recommendation}") # → DO_NOT_INSTALL
Without the multiplier, the same findings would yield a raw score of 125, which gets clamped to 100 before severity classification.
Summary
- Maximum score: 100 (hard ceiling enforced by clamping)
- Calculation location:
_compute_risk_scoreinsrc/skillspector/nodes/report.py(lines 81-101) - Base values: CRITICAL (50), HIGH (25), MEDIUM (10), LOW (5)
- Multiplier: 1.3× for bundles containing executable scripts, rounded down
- Critical threshold: ≥ 81 points triggers CRITICAL severity and DO_NOT_INSTALL recommendation
Frequently Asked Questions
What is the highest possible risk score in SkillSpector?
The highest possible risk score is 100. According to the source code in src/skillspector/nodes/report.py (lines 93-95), the algorithm clamps the calculated value to the range 0-100 after applying the executable-script multiplier, ensuring no score exceeds this maximum regardless of vulnerability count.
How does the executable script multiplier affect the maximum score?
The 1.3× multiplier can help reach the 100 ceiling with fewer base vulnerability points, but it cannot push the final score beyond 100. For example, 77 base points with the multiplier (77 × 1.3 = 100.1) truncate to 100, hitting the maximum immediately, while the same bundle without the multiplier would score only 77 (HIGH severity).
Where is the risk score calculation implemented in the SkillSpector codebase?
The core calculation logic resides in the private helper _compute_risk_score within src/skillspector/nodes/report.py. This function is invoked by the report node, which stores the results in the application state (src/skillspector/state.py) and renders them through the CLI (src/skillspector/cli.py).
What severity level corresponds to the maximum risk score of 100?
A score of 100 maps to the CRITICAL severity band (≥ 81 points), which translates to the DO_NOT_INSTALL recommendation. This mapping is defined in the _RISK_SEVERITY_BANDS and _RISK_RECOMMENDATION dictionaries at lines 55-60 and lines 96-101 of src/skillspector/nodes/report.py.
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 →