> ## Documentation Index
> Fetch the complete documentation index at: https://docs.raigal.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Scoring engine

> Calibrated 0-100 quality score, density normalization, and status bands.

Raigal assigns each repository a calibrated quality score between 0 and 100. The score measures issue density rather than raw finding counts, preventing large codebases from failing solely due to codebase volume.

## Scoring formula

Raigal evaluates findings across six diagnostic engines using density-normalized logarithmic scaling:

```text theme={null}
Deduction density = (Sum of capped deductions) / (Effective source files + S)
```

```text theme={null}
Score = max(0, round(100 - (100 * ln(1 + 5 * Deduction density)) / ln(101 + 5 * Deduction density)))
```

Where:

* **Smoothing constant (`S`)**: Defaults to `5` in configuration (internal fallback `10`). Prevents a single warning on a small project from collapsing the score.
* **Density scale**: Multiplier of `5.0` applied to deduction density.
* **Effective source files**: Count of non-excluded source and test files in the workspace (or modified files during incremental PR scans).

## Severity multipliers and engine weights

Each diagnostic finding generates a raw penalty based on its severity and parent engine:

```text theme={null}
Raw deduction = Severity multiplier * Engine weight * Tier multiplier
```

### Severity multipliers

* `error`: `3.0` (also triggers immediate exit code 1 in CI)
* `warning`: `1.0`
* `info`: `0.25`

### Engine weights

* `security`: `1.5` (secrets, injections, unsafe APIs, vulnerable dependencies)
* `architecture`: `1.0` (module boundary crossings, circular imports)
* `ai-slop`: `1.0` (swallowed exceptions, narrative comments, loose type casts)
* `code-quality`: `0.8` (dead code, complexity, parameter limits)
* `lint`: `0.6` (Oxlint, Ruff, Clippy, Roslynator)
* `format`: `0.3` (whitespace, indentation, import ordering)

## Dynamic rule capping

To ensure widespread style issues (such as 500 missing trailing commas) do not drown out security vulnerabilities or force score collapse on large projects, rules belong to impact tiers with dynamic baseline caps:

| Impact tier | Multiplier | Baseline cap | Typical findings |
| - | - | - | - |
| `strict` | `1.0x` | Uncapped (`maxPerRule`) | Syntax errors, leaked secrets, unhandled rejections |
| `standard` | `1.0x` | Uncapped (`maxPerRule`) | General linter diagnostics, compiler warnings |
| `maintainability` | `0.75x` | 24 | Cyclomatic complexity, oversized functions |
| `mechanical` | `0.5x` | 16 | Dead imports, unreferenced local variables |
| `style` | `0.5x` | 8 | Formatting variances, trailing commas |
| `advisory` | `0.25x` | 8 | Informational notices, missing docstrings |

### Repository scale scaling

The effective cap scales with repository size:

```text theme={null}
Cap scale = max(1, Effective source files / 10)
```

```text theme={null}
Effective cap = min(maxPerRule, Tier cap) * Cap scale
```

## Worked examples

### Example 1: Microservice (10 files, 1 warning)

* **Finding**: 1 `ai-slop/swallowed-exception` (`warning`, severity `1.0`, engine `1.0`, tier *strict* `1.0`).
* **Calculation**:

```text theme={null}
Deduction = 1.0
Density = 1.0 / (10 + 5) = 1.0 / 15 ≈ 0.0667
Scaled density = 0.0667 * 5.0 = 0.3333
Score = 100 - (100 * ln(1.3333) / ln(101.3333)) ≈ 100 - 6.23 = 94 (Healthy)
```

### Example 2: Monolith (200 files, 500 style findings)

* **Findings**: 500 missing trailing commas (`format/trailing-comma`, `info` `0.25`, engine `0.3`, tier *style* `0.5`, cap `8`).
* **Calculation**:

```text theme={null}
Raw deductions = 500 * 0.25 * 0.3 * 0.5 = 18.75
Cap scale = 200 / 10 = 20
Effective cap = 8 * 20 = 160
Capped deductions = min(18.75, 160) = 18.75
Density = 18.75 / (200 + 5) = 18.75 / 205 ≈ 0.0915
Scaled density = 0.0915 * 5.0 = 0.4573
Score = 100 - (100 * ln(1.4573) / ln(101.4573)) ≈ 100 - 8.15 = 92 (Healthy)
```

## Score thresholds and status bands

Raigal relies exclusively on numeric 0-100 scores. Letter grades (A-F) are not used.

### CLI status labels

When running `raigal scan` or `raigal ci`, status labels correspond to score boundaries:

| Score range | CLI label | Exit code in CI |
| - | - | - |
| `75 - 100` | `Healthy` | `0` (Passing) |
| `50 - 74` | `Needs Work` | `0` (or `1` if `ci.failBelow` is breached) |
| `< 50` | `Critical` | `1` (Fails quality gate) |

In CI environments, `raigal ci` exits with code 1 if the score is lower than `ci.failBelow` (default: 70) or if any error-level finding is detected.

### Dashboard health bands

The Raigal Cloud web interface (`app.raigal.dev`) categorizes repositories into calibrated health bands:

| Score range | Dashboard band | Color token |
| - | - | - |
| `90 - 100` | `Excellent` | Lime green |
| `75 - 89` | `Good / Healthy` | Emerald green |
| `50 - 74` | `Needs Work` | Amber / yellow |
| `< 50` | `Critical` | Red |

### Quality gate verdicts (3-state)

PR status checks and CI gates evaluate pull requests into three distinct states:

| Verdict | Criteria | Check run outcome |
| - | - | - |
| `PASSED` | Score >= 70 (or `ci.failBelow`), 0 errors, 0 warnings | `success` (Green check) |
| `PASSED (WITH WARNINGS)` | Score >= 70, 0 errors, non-blocking warnings present | `neutral` (Advisory pass, does not block merge) |
| `FAILED / BLOCKED` | Score \< 70, non-zero exit code, or blocker errors present | `failure` (Blocks merge) |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.