Product design skills

references/guidance.md

A supporting file of the ultra11y skill.

Implementation guidance — concrete before/after rules attached to criteria

A standards pack says what a criterion requires; guidance says how to implement it. It is the layer of concrete, how-to-implement rules — the RGAA SocialGouv/etalab good/bad code patterns — keyed to a pack criterion and the WCAG success criteria it maps onto. It enriches output without ever changing the verdict.

Where it shows up

Guidance is looked up at render time by criterion / WCAG SC, so the canonical audit JSON stays untouched (no schema change, no new finding). It surfaces in:

  • prd — each backlog item gains a before/after example and an effort estimate; the --format doc PRD weaves it into the user stories and acceptance criteria.
  • ultra11y_guidance over MCP — the direct lookup, by criterion.
  • ultra11y_criteria with include_guidance: true, attached to the criterion.

Because attachment is presentation-only, guidance never marks anything conforming and never invents a non-conformity — it is illustration, not detection.

Dataset shape

A guidance dataset is JSON: { pack, source, license, attribution, entries[] }, where each entry is { id, criterionId, wcag[], title, summary, impact?, examples[], reference } and an example is { lang: "html"|"jsx"|"css", bad?, good?, note? }. Two ship built in: src/data/guidance/rgaa.json (93 entries, ids mirroring the SocialGouv rule files) and src/data/guidance/wcag.json (the WCAG-keyed set). Load external guidance with --pack <dir> (a guidance.json beside pack.json) or a .ultra11yrc.json guidance list. pack check --guidance validates that every entry resolves to a real criterion, maps to recognized WCAG SCs, and that every example parses.

Inheritance — why a new country pack is useful on day one

Every entry declares the WCAG success criteria it implements, and a lookup walks every registered dataset. So a pack that ships no guidance of its own still gets examples, through the criteria it maps onto — a freshly authored Section 508 or EN 301 549 pack inherits the whole corpus the moment its wcag[] mappings exist.

Resolution order (first wins, deduped by entry id):

  1. the pack's own entry for that criterion → via: "pack", inherited: false
  2. every entry keyed to each WCAG SC the criterion maps to, in the pack's own SC order → via: "wcag:<sc>", inherited: true

The marking is the point. An inherited example is not the national standard's own doctrine, and a report that presented it as one would be making a claim nobody wrote. Every surface carries inherited / via, and each entry also carries languagesAvailable — the RGAA dataset is French-first, so an English caller must be told when an entry has no English text rather than handed French silently.

src/data/guidance/wcag.json covers all 55 AA success criteria, so no criterion is without reachable guidance for any pack — including the ten RGAA 4.1.2 never covered, six of them added in WCAG 2.2 after RGAA (wcagVersion: 2.1) froze.

It is generated, never hand-writtenscripts/build-guidance-wcag.mjs, from the W3C's own documents:

FieldComes from
which techniques applyunderstanding/understanding.11tydata.js, the W3C's machine-readable association map
summarythe Understanding document's "In brief" block (Goal / What to do / Why), verbatim
goodthe first HTML or CSS code sample in a sufficient technique
badthe first one in a documented failure
notethe technique's own title and id, so a reader can trace the sample upstream

Selection is one uniform rule, not a per-criterion choice: technologies are taken in a fixed order (html, css, aria, script, general) and within a technology the W3C's own listing order decides. Preferring HTML matters — for 1.1.1 the first technique listed with a sample is ARIA6, whose example is a navigation landmark; H2's alt="" on an image link actually illustrates a text alternative.

Two consequences worth knowing:

  • 15 criteria carry a summary and no code sample. 2.4.5 Multiple Ways and 2.5.7 Dragging Movements are site-structure and behavioural matters the W3C documents in prose. An invented snippet there would read as authoritative guidance nobody wrote.
  • The summary is English-only. Titles are bilingual (the authorized French translation covers them) but the Understanding documents are not translated, and languagesAvailable says so rather than shipping a French rendering nobody authorized.

pnpm run check:guidance:wcag fails if the committed dataset does not reproduce from the vendored snapshot, and the daily standards-refresh workflow re-fetches the W3C source, so it cannot drift from the techniques it claims to reproduce.

Honesty rule — guidance is NOT a free detector

A pattern earns a WCAG-core detector only when it is both statically decidable and maps to a success criterion present in the WCAG 2.2 AA core. Everything else lives here as guidance (and, where the country standard covers it, in the pack), never as a silent "conforming".

The headline example: opening a new window (target="_blank" without warning). Its only clean WCAG home is 3.2.5 Change on Request — which is AAA, absent from the AA core (the dataset jumps 3.2.4 → 3.2.6). So ultra11y does not ship a WCAG-core detector for it — no static rule flags target="_blank" under any standard. It ships as RGAA guidance (criterion 13.2 → WCAG 3.2.1): look it up with criteria --standard rgaa 13.2, and it attaches to the relevant prd/report entry — it is never raised as an audit non-conformity, and never force-mapped onto a wrong AA criterion. (--standard is a report/prd/criteria flag, not an audit one.) Judgment- and rendering-dependent rules (alt relevance, computed contrast, reading order) stay guidance

  • residual risk for the same reason.

Attribution

RGAA 4.1.2 © DINUM — Licence Ouverte / Etalab 2.0. The before/after implementation patterns are adapted from SocialGouv/skills (rgaa-html-css) and the official RGAA méthode; the dataset stores short derived summaries + minimal examples, not verbatim prose (see NOTICE). When ingesting another source, record its license and attribution in the dataset header and NOTICE before redistributing any text.

On this page