diff --git a/.changeset/olive-spies-jam.md b/.changeset/olive-spies-jam.md new file mode 100644 index 000000000..857032d00 --- /dev/null +++ b/.changeset/olive-spies-jam.md @@ -0,0 +1,34 @@ +--- +'@svelte-vitals/core': minor +--- + +Demote `a11y/require-datetime` and `a11y/doctype` to `info`, so each rule's weight matches the +evidence behind it. + +**Exit-code consequences, measured per rule on an isolated fixture.** Both movements loosen a gate; +nothing tightens. + +| rule | `--fail-on critical` (default) | `--fail-on warning` | `--fail-on info` | +| ----------------------- | ------------------------------ | ------------------- | ---------------- | +| `a11y/require-datetime` | 0 → 0 | **1 → 0** | 1 → 1 | +| `a11y/doctype` | 0 → 0 | **1 → 0** | 1 → 1 | + +A project running the default gate is unaffected. A project running `--fail-on warning` whose only +finding is one of these two goes from red to green. + +**Scores move too.** `a11y::component` drops from 46 to 42 points of severity weight, so every a11y +component key is scored against a smaller denominator: measured on the repository's own example +app, the a11y category reads **83 → 87** with no change in findings. `a11y::project` drops from 5 to +1, which the floor of 25 absorbs — but a project-scope finding is an absolute deduction, so a +missing doctype now costs its category 1 point rather than 5. The widest pair is unchanged at 100, +so the floor's ordering invariant is untouched. + +**Why.** Severity tracks the strength of the evidence, the standard set when the SEO severities were +aligned: + +- `a11y/require-datetime`'s requirement is HTML conformance, not an accessibility criterion. A + screen reader reads "last Tuesday" exactly as a sighted reader does; what the element loses is its + machine-readable value. +- `a11y/doctype`'s accessibility premise has no source at all — quirks mode is documented as a + layout difference, and the WCAG criterion that used to justify markup-validity checks is obsolete + and removed. The layout claim stands, so the rule stands, at the weight that claim supports. diff --git a/docs/blume.translations.json b/docs/blume.translations.json index f801a023a..56ee1e70f 100644 --- a/docs/blume.translations.json +++ b/docs/blume.translations.json @@ -55,7 +55,7 @@ "ja": "3423fd1eb16f21fd" }, "src/content/docs/rules/a11y/doctype.md": { - "ja": "545fbab226218446" + "ja": "8c76a0288d9998b1" }, "src/content/docs/rules/a11y/duplicate-landmark.md": { "ja": "2e1b5629042a8d2c" @@ -64,7 +64,7 @@ "ja": "657a9946f529dd7b" }, "src/content/docs/rules/a11y/index.mdx": { - "ja": "cec144067e19e1a6" + "ja": "5d6f9355d45752c4" }, "src/content/docs/rules/a11y/interactive-nesting.md": { "ja": "5e19d8be06bac323" @@ -85,7 +85,7 @@ "ja": "f3a20fe65f6fe0a5" }, "src/content/docs/rules/a11y/require-datetime.md": { - "ja": "153178da8c552652" + "ja": "d4741f36648af92a" }, "src/content/docs/rules/a11y/required-aria-props.md": { "ja": "fff57a22f945f5c9" @@ -181,7 +181,7 @@ "ja": "8a084d8042944616" }, "src/content/docs/rules/index.mdx": { - "ja": "67acb953dfd73379" + "ja": "d03c0a6f6112b422" }, "src/content/docs/rules/performance/font-preload-crossorigin.md": { "ja": "39baf5dc36b078e9" diff --git a/docs/src/content/docs/ja/rules/a11y/doctype.md b/docs/src/content/docs/ja/rules/a11y/doctype.md index 2fb32851c..32b6232a6 100644 --- a/docs/src/content/docs/ja/rules/a11y/doctype.md +++ b/docs/src/content/docs/ja/rules/a11y/doctype.md @@ -3,7 +3,9 @@ title: a11y/doctype · doctype がない description: src/app.html の先頭は で始めましょう。 --- -**重大度:** warning · **カテゴリ:** a11y +**重大度:** info · **カテゴリ:** a11y + +`warning` ではなく `info` としています。このルールの前提のうちアクセシビリティに関する部分には出典がないためです。互換モード(quirks mode)はレイアウトの差として文書化されており、マークアップの妥当性チェックを正当化していた WCAG の達成基準は廃止・削除されています。レイアウトに関する主張は成立するのでルール自体は残し、重みだけを残った根拠に合わせています。 ## チェック内容 diff --git a/docs/src/content/docs/ja/rules/a11y/index.mdx b/docs/src/content/docs/ja/rules/a11y/index.mdx index b83c9e55c..3b2e0e9b6 100644 --- a/docs/src/content/docs/ja/rules/a11y/index.mdx +++ b/docs/src/content/docs/ja/rules/a11y/index.mdx @@ -10,7 +10,6 @@ description: svelte-vitals の Accessibility ルール一覧。 | ルール | 重大度 | 概要 | | -------------------------------------------------------------------------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------ | | [`a11y/accessible-name`](/ja/rules/a11y/accessible-name) | 🟡 warning | ボタン・リンク・画像ボタンには、アクセシブルネームを算出できる手がかりが必要です。 | -| [`a11y/doctype`](/ja/rules/a11y/doctype) | 🟡 warning | src/app.html の先頭は <!doctype html> で始めましょう。 | | [`a11y/duplicate-landmark`](/ja/rules/a11y/duplicate-landmark) | 🟡 warning | 1つのルートに main・banner・contentinfo ランドマークはそれぞれ1つまでにしましょう。 | | [`a11y/id-duplication`](/ja/rules/a11y/id-duplication) | 🟡 warning | ルート内の id はすべて一意にしましょう。 | | [`a11y/interactive-nesting`](/ja/rules/a11y/interactive-nesting) | 🟡 warning | インタラクティブな要素を、別のインタラクティブな要素の内側に置いてはいけません。 | @@ -19,10 +18,11 @@ description: svelte-vitals の Accessibility ルール一覧。 | [`a11y/label-has-control`](/ja/rules/a11y/label-has-control) | 🟡 warning | label をフィールドと関連付けるには for 属性かラップされたコントロールが必要です。 | | [`a11y/no-missing-id-ref`](/ja/rules/a11y/no-missing-id-ref) | 🟡 warning | id参照は、合成後のルートのどこかに存在する id を指している必要があります。 | | [`a11y/placeholder-label-option`](/ja/rules/a11y/placeholder-label-option) | 🟡 warning | required かつ単一選択の select には、値を選ばせずに送信できてしまわないよう空の先頭 option が必要です。 | -| [`a11y/require-datetime`](/ja/rules/a11y/require-datetime) | 🟡 warning | time 要素のテキストは機械可読であるか、datetime 属性で機械可読な値を補う必要があります。 | | [`a11y/required-aria-props`](/ja/rules/a11y/required-aria-props) | 🟡 warning | state や property 属性を要求するロールには、ネイティブなホスト要素のセマンティクスで代替されない限り、それらの属性が必要です。 | | [`a11y/top-level-landmark`](/ja/rules/a11y/top-level-landmark) | 🟡 warning | banner・main・complementary・contentinfo ランドマークは、他のランドマークの内側に置いてはいけません。 | | [`a11y/unknown-aria-attribute`](/ja/rules/a11y/unknown-aria-attribute) | 🟡 warning | aria-\* 属性には、タイポではない実在の WAI-ARIA 属性名を指定します。 | +| [`a11y/doctype`](/ja/rules/a11y/doctype) | 🔵 info | src/app.html の先頭は <!doctype html> で始めましょう。 | +| [`a11y/require-datetime`](/ja/rules/a11y/require-datetime) | 🔵 info | time 要素のテキストは機械可読であるか、datetime 属性で機械可読な値を補う必要があります。 | | [`a11y/use-list`](/ja/rules/a11y/use-list) | 🔵 info | プレーンテキストに入力された行頭記号は、本物のリスト要素に置き換えるべきです。 | {/* rules-index:end */} diff --git a/docs/src/content/docs/ja/rules/a11y/require-datetime.md b/docs/src/content/docs/ja/rules/a11y/require-datetime.md index 25ee73c2f..bd4f85c67 100644 --- a/docs/src/content/docs/ja/rules/a11y/require-datetime.md +++ b/docs/src/content/docs/ja/rules/a11y/require-datetime.md @@ -3,7 +3,9 @@ title: a11y/require-datetime · `datetime` 属性がない description: time 要素のテキストは機械可読であるか、datetime 属性で機械可読な値を補う必要があります。 --- -**重大度:** warning · **カテゴリ:** a11y +**重大度:** info · **カテゴリ:** a11y + +`warning` ではなく `info` としています。これは HTML の適合性要件であって、アクセシビリティの達成基準ではないためです。「先週の火曜日」はスクリーンリーダーも目で見るのと同じように読み上げます — 失われるのは機械可読な値です。 ## チェック内容 diff --git a/docs/src/content/docs/ja/rules/index.mdx b/docs/src/content/docs/ja/rules/index.mdx index 6e1f44b12..695f1ce0c 100644 --- a/docs/src/content/docs/ja/rules/index.mdx +++ b/docs/src/content/docs/ja/rules/index.mdx @@ -135,7 +135,6 @@ svelte-vitals が報告するルールをカテゴリ別にまとめました。 | ルール | 重大度 | 概要 | | -------------------------------------------------------------------------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------ | | [`a11y/accessible-name`](/ja/rules/a11y/accessible-name) | 🟡 warning | ボタン・リンク・画像ボタンには、アクセシブルネームを算出できる手がかりが必要です。 | -| [`a11y/doctype`](/ja/rules/a11y/doctype) | 🟡 warning | src/app.html の先頭は <!doctype html> で始めましょう。 | | [`a11y/duplicate-landmark`](/ja/rules/a11y/duplicate-landmark) | 🟡 warning | 1つのルートに main・banner・contentinfo ランドマークはそれぞれ1つまでにしましょう。 | | [`a11y/id-duplication`](/ja/rules/a11y/id-duplication) | 🟡 warning | ルート内の id はすべて一意にしましょう。 | | [`a11y/interactive-nesting`](/ja/rules/a11y/interactive-nesting) | 🟡 warning | インタラクティブな要素を、別のインタラクティブな要素の内側に置いてはいけません。 | @@ -144,10 +143,11 @@ svelte-vitals が報告するルールをカテゴリ別にまとめました。 | [`a11y/label-has-control`](/ja/rules/a11y/label-has-control) | 🟡 warning | label をフィールドと関連付けるには for 属性かラップされたコントロールが必要です。 | | [`a11y/no-missing-id-ref`](/ja/rules/a11y/no-missing-id-ref) | 🟡 warning | id参照は、合成後のルートのどこかに存在する id を指している必要があります。 | | [`a11y/placeholder-label-option`](/ja/rules/a11y/placeholder-label-option) | 🟡 warning | required かつ単一選択の select には、値を選ばせずに送信できてしまわないよう空の先頭 option が必要です。 | -| [`a11y/require-datetime`](/ja/rules/a11y/require-datetime) | 🟡 warning | time 要素のテキストは機械可読であるか、datetime 属性で機械可読な値を補う必要があります。 | | [`a11y/required-aria-props`](/ja/rules/a11y/required-aria-props) | 🟡 warning | state や property 属性を要求するロールには、ネイティブなホスト要素のセマンティクスで代替されない限り、それらの属性が必要です。 | | [`a11y/top-level-landmark`](/ja/rules/a11y/top-level-landmark) | 🟡 warning | banner・main・complementary・contentinfo ランドマークは、他のランドマークの内側に置いてはいけません。 | | [`a11y/unknown-aria-attribute`](/ja/rules/a11y/unknown-aria-attribute) | 🟡 warning | aria-\* 属性には、タイポではない実在の WAI-ARIA 属性名を指定します。 | +| [`a11y/doctype`](/ja/rules/a11y/doctype) | 🔵 info | src/app.html の先頭は <!doctype html> で始めましょう。 | +| [`a11y/require-datetime`](/ja/rules/a11y/require-datetime) | 🔵 info | time 要素のテキストは機械可読であるか、datetime 属性で機械可読な値を補う必要があります。 | | [`a11y/use-list`](/ja/rules/a11y/use-list) | 🔵 info | プレーンテキストに入力された行頭記号は、本物のリスト要素に置き換えるべきです。 | {/* rules-index:end */} diff --git a/docs/src/content/docs/rules/a11y/doctype.md b/docs/src/content/docs/rules/a11y/doctype.md index 54a3d7561..fc6ad9b9f 100644 --- a/docs/src/content/docs/rules/a11y/doctype.md +++ b/docs/src/content/docs/rules/a11y/doctype.md @@ -3,7 +3,9 @@ title: a11y/doctype · Doctype description: src/app.html should open with . --- -**Severity:** warning · **Category:** a11y +**Severity:** info · **Category:** a11y + +Scored `info` rather than `warning`: the accessibility half of this rule's premise has no source. Quirks mode is documented as a layout difference, and the WCAG criterion that used to justify markup-validity checks is obsolete and removed. The layout claim stands, so the rule stands — at the weight its remaining evidence supports. ## What it checks diff --git a/docs/src/content/docs/rules/a11y/index.mdx b/docs/src/content/docs/rules/a11y/index.mdx index 7dfab7877..abaf7343b 100644 --- a/docs/src/content/docs/rules/a11y/index.mdx +++ b/docs/src/content/docs/rules/a11y/index.mdx @@ -10,7 +10,6 @@ ARIA validity, landmark structure, accessible names, and semantic markup — wha | Rule | Severity | Summary | | ----------------------------------------------------------------------- | ---------- | ----------------------------------------------------------------------------------------------------------------------- | | [`a11y/accessible-name`](/rules/a11y/accessible-name) | 🟡 warning | A button, link, or image button needs a way to compute its accessible name. | -| [`a11y/doctype`](/rules/a11y/doctype) | 🟡 warning | src/app.html should open with <!doctype html>. | | [`a11y/duplicate-landmark`](/rules/a11y/duplicate-landmark) | 🟡 warning | A route should have at most one main, banner, and contentinfo landmark. | | [`a11y/id-duplication`](/rules/a11y/id-duplication) | 🟡 warning | Every id in a route should be unique. | | [`a11y/interactive-nesting`](/rules/a11y/interactive-nesting) | 🟡 warning | An interactive element should not sit inside another interactive element. | @@ -19,10 +18,11 @@ ARIA validity, landmark structure, accessible names, and semantic markup — wha | [`a11y/label-has-control`](/rules/a11y/label-has-control) | 🟡 warning | A label needs a for attribute or a wrapped control to be associated with the field it names. | | [`a11y/no-missing-id-ref`](/rules/a11y/no-missing-id-ref) | 🟡 warning | An id reference should point to an id that exists somewhere in the composed route. | | [`a11y/placeholder-label-option`](/rules/a11y/placeholder-label-option) | 🟡 warning | A required, single-selection select needs an empty first option so users can't submit it unchanged. | -| [`a11y/require-datetime`](/rules/a11y/require-datetime) | 🟡 warning | A time element's text should be machine-readable, or a datetime attribute should supply the machine-readable value. | | [`a11y/required-aria-props`](/rules/a11y/required-aria-props) | 🟡 warning | A role that requires state or property attributes needs them present, unless native host semantics already supply them. | | [`a11y/top-level-landmark`](/rules/a11y/top-level-landmark) | 🟡 warning | A banner, main, complementary, or contentinfo landmark should not be nested inside another landmark. | | [`a11y/unknown-aria-attribute`](/rules/a11y/unknown-aria-attribute) | 🟡 warning | An aria-\* attribute should name a real WAI-ARIA attribute, not a typo. | +| [`a11y/doctype`](/rules/a11y/doctype) | 🔵 info | src/app.html should open with <!doctype html>. | +| [`a11y/require-datetime`](/rules/a11y/require-datetime) | 🔵 info | A time element's text should be machine-readable, or a datetime attribute should supply the machine-readable value. | | [`a11y/use-list`](/rules/a11y/use-list) | 🔵 info | A bullet character typed into plain text should be a real list element instead. | {/* rules-index:end */} diff --git a/docs/src/content/docs/rules/a11y/require-datetime.md b/docs/src/content/docs/rules/a11y/require-datetime.md index 013bb0c64..4407a3fb4 100644 --- a/docs/src/content/docs/rules/a11y/require-datetime.md +++ b/docs/src/content/docs/rules/a11y/require-datetime.md @@ -3,7 +3,9 @@ title: a11y/require-datetime · Missing datetime attribute description: A time element's text should be machine-readable, or a datetime attribute should supply the machine-readable value. --- -**Severity:** warning · **Category:** a11y +**Severity:** info · **Category:** a11y + +Scored `info` rather than `warning`: the requirement is HTML conformance, not an accessibility criterion. A screen reader reads "last Tuesday" exactly as a sighted reader does — what the element loses is its machine-readable value. ## What it checks diff --git a/docs/src/content/docs/rules/index.mdx b/docs/src/content/docs/rules/index.mdx index cad6d148d..5b397ea25 100644 --- a/docs/src/content/docs/rules/index.mdx +++ b/docs/src/content/docs/rules/index.mdx @@ -134,7 +134,6 @@ The severities below are the defaults — see [Configuration](/guides/configurat | Rule | Severity | Summary | | ----------------------------------------------------------------------- | ---------- | ----------------------------------------------------------------------------------------------------------------------- | | [`a11y/accessible-name`](/rules/a11y/accessible-name) | 🟡 warning | A button, link, or image button needs a way to compute its accessible name. | -| [`a11y/doctype`](/rules/a11y/doctype) | 🟡 warning | src/app.html should open with <!doctype html>. | | [`a11y/duplicate-landmark`](/rules/a11y/duplicate-landmark) | 🟡 warning | A route should have at most one main, banner, and contentinfo landmark. | | [`a11y/id-duplication`](/rules/a11y/id-duplication) | 🟡 warning | Every id in a route should be unique. | | [`a11y/interactive-nesting`](/rules/a11y/interactive-nesting) | 🟡 warning | An interactive element should not sit inside another interactive element. | @@ -143,10 +142,11 @@ The severities below are the defaults — see [Configuration](/guides/configurat | [`a11y/label-has-control`](/rules/a11y/label-has-control) | 🟡 warning | A label needs a for attribute or a wrapped control to be associated with the field it names. | | [`a11y/no-missing-id-ref`](/rules/a11y/no-missing-id-ref) | 🟡 warning | An id reference should point to an id that exists somewhere in the composed route. | | [`a11y/placeholder-label-option`](/rules/a11y/placeholder-label-option) | 🟡 warning | A required, single-selection select needs an empty first option so users can't submit it unchanged. | -| [`a11y/require-datetime`](/rules/a11y/require-datetime) | 🟡 warning | A time element's text should be machine-readable, or a datetime attribute should supply the machine-readable value. | | [`a11y/required-aria-props`](/rules/a11y/required-aria-props) | 🟡 warning | A role that requires state or property attributes needs them present, unless native host semantics already supply them. | | [`a11y/top-level-landmark`](/rules/a11y/top-level-landmark) | 🟡 warning | A banner, main, complementary, or contentinfo landmark should not be nested inside another landmark. | | [`a11y/unknown-aria-attribute`](/rules/a11y/unknown-aria-attribute) | 🟡 warning | An aria-\* attribute should name a real WAI-ARIA attribute, not a typo. | +| [`a11y/doctype`](/rules/a11y/doctype) | 🔵 info | src/app.html should open with <!doctype html>. | +| [`a11y/require-datetime`](/rules/a11y/require-datetime) | 🔵 info | A time element's text should be machine-readable, or a datetime attribute should supply the machine-readable value. | | [`a11y/use-list`](/rules/a11y/use-list) | 🔵 info | A bullet character typed into plain text should be a real list element instead. | {/* rules-index:end */} diff --git a/packages/cli/test/__snapshots__/gunshi-explain-parity.test.ts.snap b/packages/cli/test/__snapshots__/gunshi-explain-parity.test.ts.snap index e4a8c34f8..19fc4b736 100644 --- a/packages/cli/test/__snapshots__/gunshi-explain-parity.test.ts.snap +++ b/packages/cli/test/__snapshots__/gunshi-explain-parity.test.ts.snap @@ -170,8 +170,8 @@ a11y (15) a11y/label-has-control warning