Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
d2c7de0
docs: design score proportionality
oekazuma Aug 4, 2026
1b6e0fa
docs: fix the score-proportionality design after adversarial review
oekazuma Aug 4, 2026
1f3f2dc
docs: correct the deficit-space justification and state its residual
oekazuma Aug 4, 2026
6823627
docs: plan the score-proportionality implementation
oekazuma Aug 4, 2026
43af711
feat(core): add the per-(category, scope) rule inventory
oekazuma Aug 4, 2026
8863c86
refactor(core): fold the 'off' decision into severityOf's return type
oekazuma Aug 4, 2026
614afd4
feat(core): score a key by the share of its checks that pass
oekazuma Aug 4, 2026
a00c55f
docs(core): correct the Math.max guard's comment to name the invarian…
oekazuma Aug 4, 2026
ca70df3
test: re-baseline score expectations against the proportional model
oekazuma Aug 4, 2026
ab47c4b
test(core): exercise the fractional-deficit path in the boundary/cap …
oekazuma Aug 4, 2026
b72352f
docs: describe the proportional score model
oekazuma Aug 4, 2026
d01c4f5
test(core): re-anchor the evaluation-order score test, cover two unte…
oekazuma Aug 4, 2026
6264ec6
docs: correct routes[].score's description in the reporters guide
oekazuma Aug 4, 2026
9e4eb20
docs: name the overrides-raise overflow path in the score-proportiona…
oekazuma Aug 4, 2026
60d0495
docs: mark the design's override example as a displayed score
oekazuma Aug 4, 2026
d8220d7
fix(core): apply rule selection to an injected rule list
oekazuma Aug 4, 2026
5f21d53
docs: correct the changeset's score-change claim and record two diver…
oekazuma Aug 4, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions .changeset/score-proportionality.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
'@svelte-vitals/core': minor
'svelte-vitals': minor
'@svelte-vitals/vite': minor
---

Category scores now reflect **how much** is wrong, not merely whether anything is.

A key — a route or a source file — used to start at 100 and lose a fixed number of points per failing rule.
That capped what a category could express: `architecture` is eight `info` rules, so no amount of bad code
moved it below 92, and three more scopes bottomed out above 90. It also erased magnitude, because one
finding moves a mean of N keys by `1/N`: on a large project, one finding and several hundred displayed the
same score.

A key now scores the share of what it was measured against that is intact, weighted by severity. Every
category can reach 0, and the score moves with the number of findings.

**Any category carrying a finding changes, most of them downward and by more than a point; a clean 100 stays 100.** `seo` and `correctness` stay within a point of their old values; `architecture`, `security` and
`performance` move further, because their scales were the most compressed. A `--min-health` gate calibrated
against the old numbers will start failing — recalibrate it against the new scale. `routes[].score` in the
JSON report changes meaning the same way. Stored baselines are unaffected, since they key on findings rather
than scores.

Unchanged: the site-wide penalty stays in absolute points, a `critical` still caps a category at 79, and a
displayed 100 still means no finding among the checks that ran.
10 changes: 4 additions & 6 deletions docs/src/content/docs/guides/(reporting)/health-report.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,10 @@ Health is computed in two stages:

For each active category (SEO, Performance), svelte-vitals computes an independent score:

- Every route starts at **100**.
- Each failing finding deducts points based on severity:
- `critical` → −15 per route
- `warning` → −5 per route
- `info` → −1 per route
- Deductions are taken once per (route, rule) pair — duplicates take the maximum deduction, not a sum.
- Each route scores the share of that category's checks it was measured against — weighted by severity —
that passed: no failures scores **100**, every applicable check failing scores **0**.
- Severity sets the weight a failing check carries: `critical` weighs 15, `warning` weighs 5, `info` weighs 1.
- A failing check counts once per (route, rule) pair — duplicates take the maximum severity, not a sum.
- Route scores are averaged to produce the category's headline score.
- If any critical finding is present, the headline score is capped at **79**.

Expand Down
2 changes: 1 addition & 1 deletion docs/src/content/docs/guides/(reporting)/reporters.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ svelte-vitals --reporter json
"routes": [
{
"route": "/about", // a route id, or a source file path for file-scoped rules
"score": 95,
"score": 95, // share of this route's rule inventory (by category/scope, weighted by severity) left intact
"issues": [
{
"id": "seo/single-h1", // the rule id
Expand Down
10 changes: 4 additions & 6 deletions docs/src/content/docs/ja/guides/(reporting)/health-report.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,10 @@ Health は 2 段階で計算されます:

svelte-vitals は、アクティブなカテゴリ(SEO、パフォーマンスなど)ごとに独立したスコアを計算します:

- すべてのルートは **100** から始まります。
- 失敗した検出結果はそれぞれ、重大度に応じてポイントを差し引きます:
- `critical` → ルートごとに −15
- `warning` → ルートごとに −5
- `info` → ルートごとに −1
- 差し引きは(ルート、ルール)ペアごとに一度だけです。同じペアで重複した場合は、合計せず最大の差し引きだけを適用します。
- 各ルートは、そのカテゴリで測定対象となったチェックのうち、重大度で重み付けした上で合格した割合をスコアとします。
失敗が一つも無ければ **100**、該当するチェックがすべて失敗すれば **0** になります。
- 失敗したチェックの重みは重大度が決めます:`critical` は 15、`warning` は 5、`info` は 1 です。
- 失敗したチェックは(ルート、ルール)ペアごとに一度だけ数えます。同じペアで重複した場合は、合計せず最大の重大度を適用します。
- ルートスコアを平均してカテゴリの見出しスコアを算出します。
- クリティカルな検出結果が存在する場合、見出しスコアは **79** にキャップされます。

Expand Down
2 changes: 1 addition & 1 deletion docs/src/content/docs/ja/guides/(reporting)/reporters.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ svelte-vitals --reporter json
"routes": [
{
"route": "/about", // ルート ID。ファイル単位のルールではソースファイルのパス
"score": 95,
"score": 95, // このルートが属するカテゴリ/スコープのルール一覧(重大度で重み付け)のうち、無傷で残った割合
"issues": [
{
"id": "seo/single-h1", // ルール ID
Expand Down
Loading