ultra11y 2.31.2 → 2.31.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -10,7 +10,7 @@
10
10
  "name": "ultra11y",
11
11
  "source": "./",
12
12
  "description": "Automatic accessibility review of the code under change before every commit, push and pull request, plus full WCAG 2.2 AA / RGAA audits and conformance deliverables on demand.",
13
- "version": "2.31.2",
13
+ "version": "2.31.3",
14
14
  "author": { "name": "maxgfr" },
15
15
  "homepage": "https://github.com/maxgfr/ultra11y",
16
16
  "repository": "https://github.com/maxgfr/ultra11y",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "ultra11y",
3
3
  "description": "Accessibility for WCAG 2.2 AA and country standards (RGAA…): an automatic review of the code under change before every commit, push and pull request, plus full audits and conformance deliverables on demand.",
4
- "version": "2.31.2",
4
+ "version": "2.31.3",
5
5
  "author": { "name": "maxgfr" },
6
6
  "homepage": "https://github.com/maxgfr/ultra11y",
7
7
  "repository": "https://github.com/maxgfr/ultra11y",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "ultra11y",
3
3
  "description": "Accessibility for WCAG 2.2 AA and country standards (RGAA…): an automatic review of the code under change before every commit, push and pull request, plus full audits and conformance deliverables on demand.",
4
- "version": "2.31.2",
4
+ "version": "2.31.3",
5
5
  "author": { "name": "maxgfr", "url": "https://github.com/maxgfr" },
6
6
  "homepage": "https://github.com/maxgfr/ultra11y",
7
7
  "repository": "https://github.com/maxgfr/ultra11y",
@@ -27,7 +27,7 @@ import { fileURLToPath } from "node:url";
27
27
  // Ownership marker: `ultra11y install --opencode` refuses to overwrite a plugin file that
28
28
  // does not carry it, so a user's own ultra11y.js is never clobbered.
29
29
  const ULTRA11Y_OPENCODE_PLUGIN = "ULTRA11Y_OPENCODE_PLUGIN";
30
- const ULTRA11Y_PLUGIN_VERSION = "2.31.2";
30
+ const ULTRA11Y_PLUGIN_VERSION = "2.31.3";
31
31
 
32
32
  const here = dirname(fileURLToPath(import.meta.url));
33
33
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ultra11y",
3
- "version": "2.31.2",
3
+ "version": "2.31.3",
4
4
  "description": "Audit HTML/CSS/JSX against WCAG 2.2 AA and produce a dated compliance report, or author/review accessible markup (native-HTML-first). A skills.sh agent skill: an install-free static engine (bundled, no npm install) plus the agent's judgment, with check/verify gates against hallucinated non-conformities, and pluggable in-repo standards packs (RGAA France first; Section 508 & EN 301 549 next).",
5
5
  "type": "module",
6
6
  "packageManager": "pnpm@10.33.0",
@@ -130,6 +130,29 @@ const RULE_SC = {
130
130
  "table-caption-missing": ["1.3.1"], "table-empty-data-cell": ["1.3.1"], "title-missing-empty": ["2.4.2"],
131
131
  };
132
132
 
133
+ // ---- Judgment criteria: RGAA wordings that ask MORE than their WCAG mapping ----
134
+ // A criterion derives its status from the WCAG SCs DINUM's own crosswalk cites, and the
135
+ // projection returns `C` as soon as one mapped SC is `C`. That is right when the RGAA
136
+ // question and the SC ask the same thing (8.3 "is a default language present?" ↔ 3.1.1),
137
+ // and wrong when the RGAA wording adds a human judgment the SC never made: RGAA 8.6 asks
138
+ // whether the page title is PERTINENT, WCAG 2.4.2 only that a title exists — so a page
139
+ // titled "aaa" derived `C`. Worse, 13.3/13.4 (does each downloadable office document have
140
+ // an accessible version?) map to a bag of seven SCs including 3.1.1, so they derived `C`
141
+ // off a `lang` attribute, on pages carrying an unopened PDF — and on pages carrying no
142
+ // document at all.
143
+ //
144
+ // Only 3 WCAG SCs are `static` (1.4.2, 2.4.2, 3.1.1), so only 7 RGAA criteria can ever
145
+ // derive `C`; these are the ones among them whose question the engine has not answered.
146
+ // Flagged criteria can still be NC (a real rule fired) or NA (nothing applicable) — they
147
+ // simply never inherit a `C`, they go to the agent instead (src/standards/derive.ts).
148
+ const JUDGMENT_CRITERIA = {
149
+ "4.10": "« contrôlable par l’utilisateur » — l’arrêt/le réglage du son se constate au rendu, 1.4.2 ne prouve que l’absence d’autoplay détectable.",
150
+ "8.4": "« le code de langue est-il pertinent ? » — 3.1.1 ne vérifie que la présence et la validité syntaxique de `lang`, pas sa cohérence avec la langue réelle du contenu.",
151
+ "8.6": "« ce titre est-il pertinent ? » — 2.4.2 ne vérifie que la présence d’un `<title>` non vide.",
152
+ "13.3": "« version accessible du document en téléchargement » — aucune règle moteur ne peut ouvrir le document ; les CS mappés ne portent que sur la page.",
153
+ "13.4": "« cette version offre-t-elle la même information ? » — comparaison de deux documents, hors de portée d’un audit de la page.",
154
+ };
155
+
133
156
  // ruleId → RGAA criterion ids it evidences. Static rules + their axe:/dyn- equivalents so
134
157
  // the dynamic-tier merge keeps the same mapping (an axe:color-contrast NC still lands on
135
158
  // RGAA 3.2/10.5, not fanned out).
@@ -272,6 +295,14 @@ async function main() {
272
295
  }
273
296
  for (const c of criteria) c.appliesTo = { ruleIds: [...(critRules[c.id] ?? [])].sort() };
274
297
 
298
+ // ---- Judgment flag: attach it, and refuse to ship a stale table. A flag naming a
299
+ // criterion that could never derive `C` anyway would be silently inert, and the whole
300
+ // point is that this list stays auditable. ----
301
+ for (const id of Object.keys(JUDGMENT_CRITERIA)) {
302
+ if (!wcagById.has(id)) throw new Error(`JUDGMENT_CRITERIA: unknown RGAA criterion "${id}"`);
303
+ }
304
+ for (const c of criteria) if (JUDGMENT_CRITERIA[c.id]) c.judgment = true;
305
+
275
306
  // ---- Declarative pack RULE (usage proof): an RGAA-only ADVISORY recommendation, run by
276
307
  // the bounded interpreter (src/standards/pack-rules.ts) AFTER the core engine rules. It
277
308
  // flags a download link (`a[href$=".pdf"]` & co) whose VISIBLE TEXT states neither the