Findings and rule IDs
Which layer reports what, under which rule ID and with which severity.
Every finding carries a rule_id that names the layer, and for Schematron rules the
individual assertion. Messages are meant for people and may change; rule IDs are what code
should match on. In the shared report model, each finding’s help_url points to the section
of this page for its layer (all assertion rules share the assertion.<id> section), and
RuleInfo::help_url in the catalogue carries the same link.
| Rule ID | Layer | Severity |
|---|---|---|
parser.html5 | HTML5 tokenizer and tree construction | Error |
schema.html5 | RELAX NG schema, including attribute datatypes | Error |
assertion.<id> | Schematron rule in rules/*.sch | from the rule’s role, Error by default |
scripts.import-map | JSON content of <script type="importmap"> | Error |
scripts.speculation-rules | JSON content of <script type="speculationrules"> | Error |
csp.meta-enforcement | inline content against a meta CSP | Warning |
tables.integrity | table cell grid | Error |
text.normalization | text run not in Unicode Normalization Form C | Warning |
parser.html5
Diagnostics the HTML5 parser records while it recovers, for example an unknown named
character reference or a duplicate attribute. Set include_parse_errors: false to leave them
out of the report.
Tokenizer errors are covered completely, tree-construction errors in part: stray end tags
such as </div>, ignored start tags and misnested <b><i>…</b></i> are reported, but an end
tag that closes an element with others still open inside it (<div><span></div>) is not. See
Comparison with vnu.
schema.html5
Validation against the vendored W3C RELAX NG schema for HTML, with the SVG 1.1 and MathML 3
subtrees. This covers the content model (which element may appear where), allowed
attributes, and the value of each attribute through custom datatypes: srcset and sizes,
media queries, dates and times, URLs, BCP 47 language tags, CSP strings and others. Messages
name the offending value, for example invalid value `2026-13-01` for attribute `datetime` .
On SVG and MathML elements, an xmlns:* attribute is reported unless it is xmlns:xlink
bound to the XLink namespace.
assertion.<id>
Co-constraints the schema cannot express, written as declarative XPath rules in rules/*.sch
and evaluated with schematron-engine. The
rule ID is assertion. followed by the Schematron assertion id, for example
assertion.ids.duplicate or assertion.aria.hidden-not-focusable. The rule files cover ARIA
roles, states and restrictions, attributes, elements, headings, IDs, microdata, obsolete
elements and tables. An SVG a inside another SVG a is assertion.elements.svg-a-in-svg-a.
A rule’s role sets the severity: warning and info map to Severity::Warning and
Severity::Info, anything else to Severity::Error. The missing-lang check,
assertion.elements.html-missing-lang, is a warning.
scripts.*
The text content of <script type="importmap"> and <script type="speculationrules"> must be
valid JSON of the right shape. For example, an import map may only have the keys imports,
scopes and integrity, and the urls of a speculation rule must be an array.
csp.meta-enforcement
When a document declares a policy with <meta http-equiv="Content-Security-Policy">, its
inline script and style content is checked against script-src and style-src, each falling
back to default-src. Several meta policies apply cumulatively. A violation is a warning:
the document is still conforming HTML, but a browser would block that content.
The model is deliberately narrow. 'unsafe-inline' allows inline content, except that it is
ignored once the source list has a nonce or hash source. An inline <script> or <style> whose
nonce attribute equals a 'nonce-…' source is allowed. Hash sources are not evaluated: where
one is present the finding is an Info instead of a warning. HTTP response headers are out of
reach because the checker only sees the document.
tables.integrity
Lays each table out over its colspan and rowspan values and reports overlapping cells,
cells that span past the end of their row group, and columns in which no cell begins. This
needs state carried across cells, so it is Rust code rather than a Schematron rule.
The die Beispiele des Crates has one sample document per layer, with the findings html-conform reports for it.
text.normalization
A text run that is not in Unicode Normalization Form C is a warning, as in vnu. A text run is
the character data between two element boundaries: comments do not end it, start and end tags
and processing instructions do. The check is is_nfc of the run (the quick check plus the full
normalization where the quick check is not decisive); the message gives the NFC form of the run
as the suggested replacement. One finding per run, anchored at the first text node of the run.
Not covered, although vnu reports them: a text run, element or attribute name, or attribute value that starts with a combining character, and attribute values that are not in NFC.