ultra11y 5.11.1 → 5.11.2

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": "5.11.1",
13
+ "version": "5.11.2",
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": "5.11.1",
4
+ "version": "5.11.2",
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": "5.11.1",
4
+ "version": "5.11.2",
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 = "5.11.1";
30
+ const ULTRA11Y_PLUGIN_VERSION = "5.11.2";
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": "5.11.1",
3
+ "version": "5.11.2",
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",
@@ -6,7 +6,7 @@ import { join as join51, relative as relative5, resolve as resolve16, sep as sep
6
6
  import { fileURLToPath as fileURLToPath5, pathToFileURL as pathToFileURL3 } from "url";
7
7
 
8
8
  // src/types.ts
9
- var VERSION = "5.11.1";
9
+ var VERSION = "5.11.2";
10
10
  var SCHEMA_VERSION = 2;
11
11
 
12
12
  // src/audit.ts
@@ -57953,11 +57953,20 @@ function applyAdjudication(audit2, adj, opts = {}) {
57953
57953
  decidedBy: "agent"
57954
57954
  });
57955
57955
  }
57956
+ const alreadyDecided = new Set(
57957
+ audit2.packAdjudication?.standard === adj.standard ? audit2.packAdjudication.criteria.filter((c2) => c2.status !== "manual").map((c2) => c2.id) : []
57958
+ );
57956
57959
  for (const id of notFolded) {
57957
57960
  if (byId2.has(id) || !open.has(id)) continue;
57961
+ if (alreadyDecided.has(id)) continue;
57958
57962
  decided.push({ id, status: "manual", reason: "undecidable", justification: rejectedWhy(id), findings: [] });
57959
57963
  }
57960
- next.packAdjudication = { standard: adj.standard, criteria: decided };
57964
+ const carried = /* @__PURE__ */ new Map();
57965
+ if (audit2.packAdjudication?.standard === adj.standard) {
57966
+ for (const c2 of audit2.packAdjudication.criteria) carried.set(c2.id, c2);
57967
+ }
57968
+ for (const c2 of decided) carried.set(c2.id, c2);
57969
+ next.packAdjudication = { standard: adj.standard, criteria: [...carried.values()] };
57961
57970
  next.findings = [...next.findings, ...newFindings];
57962
57971
  next.adjudicated = { date: adj.auditDate, applied, stillManual, ...rejectedCriteria.length ? { rejected: rejectedCriteria.length } : {} };
57963
57972
  return { ok: issues.length === 0, audit: next, issues, applied, stillManual, rejected: rejectedCriteria.length, rejectedCriteria, grounding };
@@ -5,7 +5,7 @@ when_to_use: "Invoke WITHOUT being asked whenever changed front-end code should
5
5
  allowed-tools: Bash(node ${CLAUDE_SKILL_DIR}/scripts/ultra11y.mjs *), Read, Grep, Glob
6
6
  license: MIT
7
7
  metadata:
8
- version: 5.11.1
8
+ version: 5.11.2
9
9
  ---
10
10
 
11
11
  # review-a11y — accessibility review of changed code
@@ -6,7 +6,7 @@ import { join as join51, relative as relative5, resolve as resolve16, sep as sep
6
6
  import { fileURLToPath as fileURLToPath5, pathToFileURL as pathToFileURL3 } from "url";
7
7
 
8
8
  // src/types.ts
9
- var VERSION = "5.11.1";
9
+ var VERSION = "5.11.2";
10
10
  var SCHEMA_VERSION = 2;
11
11
 
12
12
  // src/audit.ts
@@ -57953,11 +57953,20 @@ function applyAdjudication(audit2, adj, opts = {}) {
57953
57953
  decidedBy: "agent"
57954
57954
  });
57955
57955
  }
57956
+ const alreadyDecided = new Set(
57957
+ audit2.packAdjudication?.standard === adj.standard ? audit2.packAdjudication.criteria.filter((c2) => c2.status !== "manual").map((c2) => c2.id) : []
57958
+ );
57956
57959
  for (const id of notFolded) {
57957
57960
  if (byId2.has(id) || !open.has(id)) continue;
57961
+ if (alreadyDecided.has(id)) continue;
57958
57962
  decided.push({ id, status: "manual", reason: "undecidable", justification: rejectedWhy(id), findings: [] });
57959
57963
  }
57960
- next.packAdjudication = { standard: adj.standard, criteria: decided };
57964
+ const carried = /* @__PURE__ */ new Map();
57965
+ if (audit2.packAdjudication?.standard === adj.standard) {
57966
+ for (const c2 of audit2.packAdjudication.criteria) carried.set(c2.id, c2);
57967
+ }
57968
+ for (const c2 of decided) carried.set(c2.id, c2);
57969
+ next.packAdjudication = { standard: adj.standard, criteria: [...carried.values()] };
57961
57970
  next.findings = [...next.findings, ...newFindings];
57962
57971
  next.adjudicated = { date: adj.auditDate, applied, stillManual, ...rejectedCriteria.length ? { rejected: rejectedCriteria.length } : {} };
57963
57972
  return { ok: issues.length === 0, audit: next, issues, applied, stillManual, rejected: rejectedCriteria.length, rejectedCriteria, grounding };
@@ -4,7 +4,7 @@ description: "Use to AUDIT existing HTML/CSS/JSX against WCAG 2.2 AA accessibili
4
4
  when_to_use: "Invoke when the user asks for an accessibility AUDIT or a formal deliverable: audit a repo, site or page against WCAG 2.2 AA or a country standard (RGAA, Section 508, EN 301 549); produce a dated conformance report, a criterion grid, a PRD backlog, or tickets (GitHub/GitLab/Jira); author accessible markup from scratch; wire the repo gate (init --hook/--ci) or a rendered-DOM capture pipeline. For a review of the code UNDER CHANGE (diff, branch, PR), use the `review-a11y` skill instead."
5
5
  license: MIT
6
6
  metadata:
7
- version: 5.11.1
7
+ version: 5.11.2
8
8
  ---
9
9
 
10
10
  # ultra11y — audit WCAG 2.2 AA and write accessible markup
@@ -6,7 +6,7 @@ import { join as join51, relative as relative5, resolve as resolve16, sep as sep
6
6
  import { fileURLToPath as fileURLToPath5, pathToFileURL as pathToFileURL3 } from "url";
7
7
 
8
8
  // src/types.ts
9
- var VERSION = "5.11.1";
9
+ var VERSION = "5.11.2";
10
10
  var SCHEMA_VERSION = 2;
11
11
 
12
12
  // src/audit.ts
@@ -57953,11 +57953,20 @@ function applyAdjudication(audit2, adj, opts = {}) {
57953
57953
  decidedBy: "agent"
57954
57954
  });
57955
57955
  }
57956
+ const alreadyDecided = new Set(
57957
+ audit2.packAdjudication?.standard === adj.standard ? audit2.packAdjudication.criteria.filter((c2) => c2.status !== "manual").map((c2) => c2.id) : []
57958
+ );
57956
57959
  for (const id of notFolded) {
57957
57960
  if (byId2.has(id) || !open.has(id)) continue;
57961
+ if (alreadyDecided.has(id)) continue;
57958
57962
  decided.push({ id, status: "manual", reason: "undecidable", justification: rejectedWhy(id), findings: [] });
57959
57963
  }
57960
- next.packAdjudication = { standard: adj.standard, criteria: decided };
57964
+ const carried = /* @__PURE__ */ new Map();
57965
+ if (audit2.packAdjudication?.standard === adj.standard) {
57966
+ for (const c2 of audit2.packAdjudication.criteria) carried.set(c2.id, c2);
57967
+ }
57968
+ for (const c2 of decided) carried.set(c2.id, c2);
57969
+ next.packAdjudication = { standard: adj.standard, criteria: [...carried.values()] };
57961
57970
  next.findings = [...next.findings, ...newFindings];
57962
57971
  next.adjudicated = { date: adj.auditDate, applied, stillManual, ...rejectedCriteria.length ? { rejected: rejectedCriteria.length } : {} };
57963
57972
  return { ok: issues.length === 0, audit: next, issues, applied, stillManual, rejected: rejectedCriteria.length, rejectedCriteria, grounding };
package/src/adjudicate.ts CHANGED
@@ -1003,11 +1003,34 @@ export function applyAdjudication(
1003
1003
  // An OPEN criterion the file never mentioned — a coverage gap, or one the caller declared
1004
1004
  // uncovered — also has to say why it is still to assess; the loop above only walks the
1005
1005
  // items that exist.
1006
+ const alreadyDecided = new Set(
1007
+ audit.packAdjudication?.standard === adj.standard ? audit.packAdjudication.criteria.filter((c) => c.status !== "manual").map((c) => c.id) : [],
1008
+ );
1006
1009
  for (const id of notFolded) {
1007
1010
  if (byId.has(id) || !open.has(id)) continue;
1011
+ // …and never over a verdict an earlier pass already landed: this loop exists to explain
1012
+ // an OPEN criterion, not to reopen a closed one.
1013
+ if (alreadyDecided.has(id)) continue;
1008
1014
  decided.push({ id, status: "manual", reason: "undecidable", justification: rejectedWhy(id), findings: [] });
1009
1015
  }
1010
- next.packAdjudication = { standard: adj.standard, criteria: decided };
1016
+ // MERGE, never replace. A fold used to write `packAdjudication` from the file it was
1017
+ // given and nothing else, which is fine for one fold and wrong for two: a later pass
1018
+ // re-derives its worklist from what is STILL open, so a criterion decided earlier is
1019
+ // ABSENT from it by construction — and rewriting the set dropped it back to « à évaluer ».
1020
+ //
1021
+ // Measured on the first three-pass run: 47 criteria, 5 refused → 41 left; the next pass
1022
+ // ruled those, 4 refused → and the third opened with 47 again. Each pass was undoing the
1023
+ // one before it, so the tier could never converge however much it was allowed to spend.
1024
+ //
1025
+ // What the file rules wins for its own criteria — a pass that names a criterion decides it,
1026
+ // even against an earlier verdict — and everything else it does not mention stays as it
1027
+ // was. Only entries of the SAME standard carry over; a pack change starts a clean sheet.
1028
+ const carried = new Map<string, PackCriterionAdjudication>();
1029
+ if (audit.packAdjudication?.standard === adj.standard) {
1030
+ for (const c of audit.packAdjudication.criteria) carried.set(c.id, c);
1031
+ }
1032
+ for (const c of decided) carried.set(c.id, c);
1033
+ next.packAdjudication = { standard: adj.standard, criteria: [...carried.values()] };
1011
1034
  // The agent's findings still join the flat list so grounding, `check` and the reports can
1012
1035
  // resolve them — but they never touch a WCAG criterion's status.
1013
1036
  next.findings = [...next.findings, ...newFindings];
package/src/types.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  // Single source of truth for shared types + the embedded version. sync-version.mjs
2
2
  // rewrites VERSION at release time (kept in lockstep with package.json + SKILL.md).
3
- export const VERSION = "5.11.1";
3
+ export const VERSION = "5.11.2";
4
4
  export const SCHEMA_VERSION = 2;
5
5
 
6
6
  // Lang = the UI FRAME's language — the `L` localization tables each module (report,