Scoring
How the 0–100 score is computed — formula, severity weights, density scaling, and the per-criterion cap.
The formula
penalty_raw = Σ (severity_weight × issue) per criterion, capped at MAX
scaleFactor = 1 / (1 + log10(files_scanned))
penalty_scaled = penalty_raw × scaleFactor
score = round( 100 × exp(-k × penalty_scaled) )With k = 0.02 and MAX_PENALTY_PER_CRITERION = 15. The curve is asymptotic — no scan ever scores exactly 0.
Severity weights
| Severity | Weight |
|---|---|
| critical | 10 |
| serious | 5 |
| moderate | 2 |
| minor | 1 |
Critical issues cost 10× more than minor ones. Two critical issues outweigh twenty minor ones.
Density scaling
Without scaling, a 1,000-file repo with 10 issues would score worse than a 10-file repo with 10 issues — even though the first is clearly healthier relative to its size. The scaleFactor divides the raw penalty by 1 + log10(files), flattening the difference.
| Files scanned | scaleFactor |
|---|---|
| 1 | 1.00 |
| 10 | 0.50 |
| 100 | 0.33 |
| 1,000 | 0.25 |
Per-criterion cap
Without a cap, a single spammy rule (say, 200 missing alt attributes) would dwarf every other issue. MAX_PENALTY_PER_CRITERION = 15 means the same criterion can contribute at most 15 penalty points, regardless of occurrence count. Adding a 201st missing alt to the same criterion costs nothing — the score is already maxed out on that one.
Conformance level
Separately from the score, Equall computes a WCAG conformance level: None, Partial A, A, AA, or AAA. The rule:
- Any Level A violation →
Partial A - Zero Level A, any Level AA violation →
A - Zero Level A and AA, any Level AAA →
AA - All clean → highest level the scan covered
Best-practice issues (no WCAG mapping) never affect the conformance level — they only appear in the Best-Practice Recommendations section of the output.
POUR breakdown
Every WCAG criterion belongs to one of four principles — Perceivable, Operable, Understandable, Robust. The POUR breakdown runs the same formula isolated to each principle, giving four sub-scores. Principles with no covered criteria show n/a.