# How to Interpret SkillSpector Risk Scores and Severity Levels on the 0-100 Scale

> Understand SkillSpector risk scores and severity levels from 0-100. Learn how findings, script multipliers, and severity bands define risk, from LOW to CRITICAL.

- Repository: [NVIDIA Corporation/SkillSpector](https://github.com/NVIDIA/SkillSpector)
- Tags: tutorials
- Published: 2026-06-22

---

**SkillSpector calculates risk scores from 0 to 100 by assigning fixed weights to findings (CRITICAL=50, HIGH=25, MEDIUM=10, LOW=5), applies a 1.3x multiplier if executable scripts are detected, then maps the result to severity bands where scores 81+ indicate CRITICAL risk and 0-20 indicate LOW risk.**

NVIDIA/SkillSpector is an open-source security analysis framework that evaluates skill bundles and quantifies risk using a standardized 0-100 scale. Understanding how to interpret these risk scores and severity levels is essential for making informed deployment decisions. This guide breaks down the scoring algorithm, severity thresholds, and recommendation logic as implemented in the source code.

## How SkillSpector Calculates Risk Scores

The scoring logic resides in [`src/skillspector/nodes/report.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/nodes/report.py) within the `_compute_risk_score` function. The calculation follows a deterministic two-phase process: base accumulation from findings and conditional multipliers.

### Base Scoring Weights

Each security finding contributes a fixed point value based on its severity classification:

- **CRITICAL**: +50 points
- **HIGH**: +25 points
- **MEDIUM**: +10 points
- **LOW**: +5 points

These weights are hardcoded in the `_compute_risk_score` function (lines 78-92). The engine iterates through all findings in the skill bundle and accumulates the sum based on each finding's severity level as defined in [`src/skillspector/models.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/models.py).

### Executable Script Multiplier

If the bundle contains any executable scripts, SkillSpector applies a **1.3x multiplier** to the total score. This boost reflects the increased attack surface posed by executable code. The final score is capped at 100 to maintain the bounds of the scale, as implemented in lines 92-94 of [`report.py`](https://github.com/NVIDIA/SkillSpector/blob/main/report.py).

## Severity Bands and Recommendations

After calculating the numeric score, SkillSpector maps it to a severity band using thresholds defined in `_RISK_SEVERITY_BANDS` (lines 54-56). The mapping logic iterates through thresholds in descending order until finding the appropriate match (lines 96-101).

| Score ≥ | Severity | Recommendation |
|---------|----------|----------------|
| 81 | **CRITICAL** | DO_NOT_INSTALL |
| 51 | **HIGH** | DO_NOT_INSTALL |
| 21 | **MEDIUM** | CAUTION |
| 0 | **LOW** | SAFE |

The recommendation strings are defined in `_RISK_RECOMMENDATION` (lines 56-60). A score of 50 falls into MEDIUM severity with a CAUTION recommendation, while 51 shifts to HIGH severity with a DO_NOT_INSTALL recommendation.

## Accessing Risk Data Programmatically

The risk assessment data is stored in the graph state ([`src/skillspector/state.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/state.py), lines 66-71) as `risk_score`, `risk_severity`, and `risk_recommendation`. When using the JSON output format, these values appear under the `risk_assessment` key.

```python
import subprocess
import json
import pathlib

skill_path = pathlib.Path("/path/to/skill")
result = subprocess.run(
    ["skillspector", str(skill_path), "--output-format", "json"],
    capture_output=True,
    text=True,
    check=True
)

report = json.loads(result.stdout)
risk = report["risk_assessment"]

print(f"Risk score: {risk['score']}/100")
print(f"Severity:   {risk['severity']}")
print(f"Action:     {risk['recommendation']}")

```

Typical output:

```text
Risk score: 55/100
Severity:   HIGH
Action:     DO_NOT_INSTALL

```

## Implementation Details

The severity scoring depends on the `Finding` model defined in [`src/skillspector/models.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/models.py), which provides the `severity` field that drives the point accumulation. Unit tests in [`tests/nodes/test_report.py`](https://github.com/NVIDIA/SkillSpector/blob/main/tests/nodes/test_report.py) verify the scoring arithmetic and band mapping logic, ensuring edge cases like threshold boundaries (e.g., exactly 50 vs. 51 points) are handled correctly according to the `_RISK_SEVERITY_BANDS` definitions.

## Summary

- **SkillSpector risk scores** range from 0 (lowest risk) to 100 (highest risk).
- **Base scoring** assigns CRITICAL findings 50 points, HIGH 25 points, MEDIUM 10 points, and LOW 5 points.
- **Executable scripts** trigger a 1.3x multiplier capped at 100.
- **Severity bands** use thresholds at 21, 51, and 81 to delineate LOW, MEDIUM, HIGH, and CRITICAL risks.
- **Recommendations** map LOW to SAFE, MEDIUM to CAUTION, and HIGH/CRITICAL to DO_NOT_INSTALL.
- **Access risk data** via the `risk_assessment` object in JSON output or the state fields in [`src/skillspector/state.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/state.py).

## Frequently Asked Questions

### What is the maximum possible SkillSpector risk score?

The maximum score is **100**. Even if the weighted sum of findings exceeds 100 or the 1.3x executable script multiplier pushes the total higher, the `_compute_risk_score` function in [`src/skillspector/nodes/report.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/nodes/report.py) caps the final value at 100.

### How does SkillSpector distinguish between HIGH and MEDIUM risk?

The threshold is set at **51 points**. A score of 50 or below maps to MEDIUM severity with a CAUTION recommendation, while 51 or above maps to HIGH severity with a DO_NOT_INSTALL recommendation. This boundary is defined in `_RISK_SEVERITY_BANDS` in the report node.

### Why does SkillSpector multiply scores by 1.3 for executable scripts?

Executable scripts pose elevated security risks because they can run arbitrary code on the target system. The **1.3x multiplier** reflects this increased attack surface and potential for malicious behavior, ensuring that bundles containing executables receive appropriately higher risk ratings before the final cap is applied.

### Where can I find the risk assessment data in the output?

Risk data is stored in three locations: the internal graph state (`risk_score`, `risk_severity`, `risk_recommendation` in [`src/skillspector/state.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/state.py)), the JSON output under the `risk_assessment` key, and in formatted text or markdown reports. All formats consume the same underlying values computed by `_compute_risk_score`.