Quality Ratings
Every completed scan gets five A–E ratings + a total tech-debt estimate. This page shows the exact math.
The Five Ratings
| Rating | What it measures | Primary inputs |
|---|---|---|
| Overall | Composite — worst of the four below | min(reliability, maintainability, coverage, duplication) |
| Reliability | Likelihood of runtime bugs | complexity + dead-code + SAST critical/high |
| Maintainability | Change safety | complexity + duplication + dead-code |
| Coverage | Test completeness | ingested coverage reports, aggregate line % |
| Duplication | Copy-paste code | jscpd summary (total duplication % of LOC) |
Missing data (no coverage report, no jscpd summary) → rating is null, not a fake grade. The dashboard renders a greyed-out badge with a shield icon.
A–E Thresholds
Severity-driven ratings (reliability, maintainability)
| Rating | Criterion (counts findings of matching type + severity in scan) |
|---|---|
| A | 0 critical + 0 high |
| B | 0 critical + ≤ 2 high |
| C | 0 critical + ≤ 10 high |
| D | ≤ 2 critical |
| E | 3+ critical |
Coverage rating
| Rating | Coverage % (from ingested lcov/cobertura/jacoco/clover) |
|---|---|
| A | ≥ 90% |
| B | ≥ 80% |
| C | ≥ 60% |
| D | ≥ 40% |
| E | < 40% |
Duplication rating
| Rating | Duplication % (from jscpd summary) |
|---|---|
| A | < 1% |
| B | < 3% |
| C | < 5% |
| D | < 10% |
| E | ≥ 10% |
Composite
composite = max(reliability, maintainability, coverage, duplication) — the worst letter wins (since letters are ordered A..E lexicographically, max = worst).
Missing ratings are ignored (they don’t drag the composite down).
Tech Debt Hours
CodeStax implements a simplified SQALE model. Every rule maps to a remediation-minute estimate:
Rule Minutes
─────────────────────────────────────
radon-cc-C (complexity C) 20
radon-cc-D 45
radon-cc-E 90
radon-cc-F (very complex) 180
lizard-cc-* 20-180
radon-mi (maintainability) 60
cognitive-complexity 30
vulture-unused 5
knip-unused-file 10
knip-unused-export 5
jscpd-duplicate 30
coverage-below-threshold 15
default (unknown rule) 10The scan’s total tech_debt_minutes = sum of above for non-FP findings. Exposed as:
tech_debt_minutes(raw) onScanResulttech_debt_hours = round(minutes / 60, 2)tech_debt_engineer_days = round(minutes / 480, 2)(8-hour days)
API:
GET /api/quality/tech-debt/{scan_id}
{
"scan_id": 12345,
"total_minutes": 847,
"total_hours": 14.12,
"total_engineer_days": 1.76,
"findings_by_type": {
"complexity": 23,
"dead_code": 8,
"duplication": 5,
"coverage_gap": 12
}
}FP-Marked Findings
Findings with user_marked_fp = true are excluded from tech-debt totals + rating counts. See Mark False Positives.
Deterministic
Ratings are a pure function of the findings list. Same scan → same ratings. See Reproducibility.
Parse Coverage
Each scan also reports parse coverage — the % of files the scanner could successfully read. Low parse coverage = underestimates in ratings. Visible in Quality Insights → collapsible “Scan metadata”:
parse_coverage_pct: 98.2
files_parsed: 1847
files_skipped: 34If parse coverage < 95%, the dashboard surfaces it in yellow as a warning.
Viewing Ratings
- Scan detail page — Quality Insights panel shows all 5 ratings as badges + tech-debt hours + engineer-days
- API:
GET /api/quality/ratings/:scan_id - Historical trend — coming soon (ratings are recorded per scan; aggregation view on roadmap)