Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
18 changes: 18 additions & 0 deletions .changeset/route-category-scores.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
'@svelte-vitals/core': minor
'svelte-vitals': minor
'@svelte-vitals/vite': minor
---

Each entry in the JSON report's `routes` array now carries a `categories` map of category name to score.

A category's score is an average over its keys, so a category that looks wrong gives no clue which routes
produced it. The report listed each route's findings but not what each route scored per category, and since a
key's score became a ratio against the severity-weighted inventory of the checks it was measured against, that
number is no longer something a reader can reconstruct by hand.

Only the categories that produced a result on a route appear, so an absent category means "not measured here"
rather than "perfect here". A route's `categories` values are **not guaranteed** to average to its `score`:
`score` is one ratio over everything the route was measured against, while each category score uses that
category's own inventory. They agree whenever every category on the route scores the same ratio — including
every route with no findings — and can differ by several points otherwise.
3 changes: 3 additions & 0 deletions docs/src/content/docs/guides/(reporting)/reporters.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ svelte-vitals --reporter json
{
"route": "/about", // a route id, or a source file path for file-scoped rules
"score": 95, // share of this route's rule inventory (by category/scope, weighted by severity) left intact
"categories": { "seo": 94 }, // per category present on this route, scored against that category's own inventory
"issues": [
{
"id": "seo/single-h1", // the rule id
Expand Down Expand Up @@ -81,6 +82,8 @@ Two field names are worth pointing out, because guessing them wrongly fails sile

`line`, `docsUrl` and `fix` are present only when the rule supplies them, and `location` only for a finding tied to a file. `issues` lists **failing** findings only — passing checks are counted in `summary.passed` but are not listed. A route with no failures still appears in `routes`, with an empty `issues` array and its own score.

`categories` holds only the categories that produced a result on that route — an absent category means "not measured here," not "perfect here." Its values are **not guaranteed** to average to the route's own `score`, in either direction: `score` is one ratio over everything the route was measured against, while each category score uses that category's own inventory. They agree whenever every category on the route scores the same ratio (including every route with no findings) and can differ by several points otherwise.

`rules` answers a question the rest of the report cannot: **whether a rule ran at all.** `issues` lists
only failing findings, so a rule that found nothing leaves no trace there — and a rule disabled at the top
level (`--ignore`, `--rules`, `--category`, or `rules: { id: 'off' }` in config) leaves the same absence.
Expand Down
3 changes: 3 additions & 0 deletions docs/src/content/docs/ja/guides/(reporting)/reporters.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ svelte-vitals --reporter json
{
"route": "/about", // ルート ID。ファイル単位のルールではソースファイルのパス
"score": 95, // このルートが属するカテゴリ/スコープのルール一覧(重大度で重み付け)のうち、無傷で残った割合
"categories": { "seo": 94 }, // このルートで結果が出たカテゴリごとのスコア。そのカテゴリ自身の一覧に対する割合
"issues": [
{
"id": "seo/single-h1", // ルール ID
Expand Down Expand Up @@ -81,6 +82,8 @@ svelte-vitals --reporter json

`line`・`docsUrl`・`fix` はルールが提供した場合のみ、`location` はファイルに紐づく検出の場合のみ現れます。`issues` に並ぶのは**失敗した検出のみ**です。合格したチェックは `summary.passed` に数として計上されますが、一覧には出ません。失敗が1件も無いルートも `routes` には現れ、`issues` が空配列のまま自分のスコアを持ちます。

`categories` にはそのルートで実際に結果が出たカテゴリだけが並びます。あるカテゴリが無いのは「ここでは測定していない」という意味であり、「ここは満点だった」という意味ではありません。この値がルート自身の `score` の平均になっているとは、どちらの向きにも**保証されません**。`score` はそのルートが測定対象とした全体に対する一つの割合であるのに対し、各カテゴリのスコアはそのカテゴリ自身の一覧に対する割合だからです。ルート上のすべてのカテゴリが同じ割合を示すとき(検出結果が無いルートも含む)は両者が一致し、それ以外では数ポイントずれることがあります。

`rules` は、レポートの他の部分では答えられない問い、**そのルールがそもそも実行されたかどうか**に答えます。`issues` に載るのは失敗した検出結果だけなので、何も検出しなかったルールはそこに痕跡を残しません。トップレベルで無効化した(`--ignore`、`--rules`、`--category`、または設定ファイルの `rules: { id: 'off' }`)ルールも同じく現れません。判定には `rules` を見ます。存在すれば実行された、存在しなければトップレベルで除外された、という意味です。ただし一つだけ例外があり、それは次に述べます。

件数が表すのはツリーではなくレポートそのものです。baseline、抑制、`--diff` によるフィルタリングはレポートを組み立てる前に適用されるため、検出結果がすべて抑制されたルールも `findings: 0` のまま `rules` に残ります。`overrides` で無効化したルールも同様です。トップレベルとは異なり、`overrides` はルールが実行された後にその結果(合格分も含む)を取り除くため、`{ "findings": 0, "passed": 0 }` として現れ、選択されて何も検出しなかったルールと見分けがつきません。`rules` に存在することが保証するのは、`--ignore`・`--rules`・`--category`・設定ファイルのトップレベルの `rules` で除外されなかったことだけで、`overrides` が検出結果を何も残さなかったことまでは保証しません。
Expand Down
Loading