ultra11y — 根据 WCAG 2.2 AA 审计并编写无障碍标记
在无障碍方面,自动化工具只能看到问题的一部分。ultra11y 通过一种分工机制解决了这个问题:确定性的、无需安装的引擎(node scripts/ultra11y.mjs <command> — 无需 npm install,无需密钥;JSX/TSX 解析器内嵌在包中)负责执行机械性工作 — 检测机器可查的不合规项,并将每个不合规项与正确的 WCAG 成功标准 关联起来 — 而 活跃的编码代理 则负责裁决需要判断的标准本身 — 替代文本的相关性、链接在上下文中的目的、阅读顺序 — 所有裁决都是静态地基于引擎收集的证据(verify --manual),每个裁决结果都经过 verify/check 关卡的检查。只有那些真正需要渲染 DOM 的标准(计算后的对比度、可见焦点、缩放/重排、悬停时显示的内容)才属于 scan 层级(在真实浏览器中使用 axe-core);人工监督最多是可选的。这些关卡可以防止任何被幻觉出来的不合规项存活下来,并且任何内容都不会被静默地标记为“合规”。
不要混淆规则与标准。 该包提供 93 项静态检查,WCAG AA 有 55 个成功标准,而 RGAA 有 106 个标准。多个规则可能为同一个标准提供证据,一个规则也可能为多个标准包提供贡献,并且大多数标准在扫描或裁决完成之前仍处于未决状态。唯一诚实的运行级覆盖率是网格中实时的来源统计(moteur + scan + agent,加上任何命名的不可判定残留项),而绝非一个固定的承诺,例如“48 个代理标准”。因此,GitHub 摘要显示 decided/total,而不是针对已判定子集计算百分比。
WCAG 2.2 Level AA 是全球核心。 各国标准 — 法国的 RGAA、美国的 Section 508、欧盟的 EN 301 549 — 都是可插拔的标准包,它们将自己的标准映射到 WCAG 上。添加 --standard rgaa 可以重新定义每条命令和每个输出 — audit 命令也包括在内,其发现结果也是如此;在运行时使用 --pack ./pack.json(或 .ultra11yrc.json)插入外部包,无需重建;或者贡献您所在国家的标准(参见 references/standards.md)。这些包(及其具体的实施指南 — RGAA SocialGouv/etalab 好/坏模式)可以被 AI 摄取,并通过 pack check 进行把关,从而避免伪造的映射通过 — 参见 references/packs.md 和 references/guidance.md。
大部分工作由您完成。 在 55 个 WCAG 2.2 AA 成功标准中,引擎可以直接判定3 个;14 个需要渲染页面(scan),38 个是代理需要裁决的判断性调用。因此,引擎的干净运行只是一个起点,而非最终判决 — 而 references/adjudication.md 才是您真正需要参考的页面。
核心规则:
- 切勿虚构不合规项:每条
NC都必须引用一个真实的、可解析的元素(check会验证它)。- 优先使用原生 HTML,最后才考虑 ARIA;切勿重复隐式语义。
- 切勿虚构合规项:
C的引用方式与NC完全相同 — 它在citations[]中列出其通过的已收集证据,每个锚点都是可解析的,并且来自该标准实际展示的证据。一个没有证据支持的标准根本不能标记为C;它必须保持manual状态。同样,如果一个标准的阅读状态为 INCOMPLETE(evidenceComplete: false),也不能标记为C:一个您只看到部分内容的标准仍可能因您看到的内容而失败,但它绝不能因为您没有看到的内容而被清除。而且,由代理裁决的C永远不会与引擎判定的C合并:报告会单独列出它们,并将其排除在自动通过率之外。 3b. 展示给您的是完整的数据集,每个不同的内容只会表述一次。 证据是每个 CONTENT CLASS 的一个代表性实例,包含occurrences、其他锚点位于alsoAt以及它出现的pages— 跨越 38 个捕获页面的 887 个链接被归类为 97 个不同的(text, href)对。对代表实例做出裁决即意味着对所有实例做出裁决,这才是使得一个诚实的C变得可达成的关键;并且,引用该类中该标准所携带的任何一个实例的引用都被接受,因此请引用您实际打开的那个。- 残留项是明确声明的,永远不会被静默地标记为合规:AI 代理裁决每个需要判断的标准本身(
verify --manual,经过把关),而渲染相关的标准则交由scan处理 — 当携带某个标准的所有规则都在作用域内的每个页面上运行且未发现问题时,scan现在会给出C结论(decidedBy: "scan"),并且当即使只有一个页面的信号不完整时也会保持静默。任何仍未证实的标准都会保持“待人工评估”状态 — 没有状态可以在没有记录且合理的判决的情况下存在。为了使其成为一个关卡而不是一个希望,check --in <audit.json> --require-decided命令会在任何内容仍处于待评估状态时失败,而--allow-undecided <file>命令则接收您确实无法判定的标准,每个标准都附有其原因(一个命名的列表,而不是一个阈值)。--require-decided=pages要求每个页面的网格都遵守相同的标准:一个标准在某一路径上失败意味着这次运行已解决,但对于它从未触发过的路径可能仍不是任何人的判决,而每个页面的可交付成果正是基于此进行评审的。 发出的工作列表是权威的。 它可能故意包含一个在全局状态上已经是NC的标准,因为这次失败并未在其他页面上判定该标准。这样的条目并非多余:请为其返回一个基于事实的裁决(或一个明确的manual理由),切勿因为全局统计看起来已经判定就留空。- 查阅标准;切勿凭记忆回忆。 使用
criteria [--standard <pack>] <id>命令 — 或通过 MCP 使用ultra11y_criteria— 返回标准本身的措辞、其编号的测试项以及这些测试所引用的术语表定义。RGAA 8.3 并非“页面需要lang属性”;它是测试8.3.1,包含两个替代条件,而其术语的含义由术语表决定。一个在阅读了8.3.1后进行引用的审计块是可靠的;而一个凭记忆引用它的审计块则是一个披着引用外衣的猜测。在针对国家/地区标准进行审计之前,请运行计划(ultra11y_method):它会告诉您还有多少标准需要裁决才能获得 C — 对于 RGAA,106 个中有 104 个。参见references/mcp.md。- 最终渲染的语义 HTML 必须是正确的。 引擎仅能看到源代码;组件库 (DSFR/MUI…) 或
.vue/.svelte/.astro单文件组件隐藏了真实的标记,因此源代码审计通过并不能作为证明。请验证生成的语义 HTML — 安装零接触的 capture 收集器(render --setup),这样您的测试渲染的每个组件都会被序列化到.ultra11y/captures目录并进行审计,使用audit --require-captures来把关盲区。参见references/automation.md/references/rendered.md。- 语言:始终传递与您和用户对话语言相匹配的
--lang参数;当存在歧义时,请询问用户。如果没有该标志,CLI 会自动检测(仓库的<html lang>→ 当前活动标准的默认区域设置 → 英语) — 这是一个脚本/CI 的备用方案,不能替代您自己传递--lang参数。- 技术性标记使用英文,即使是在法语文档中也是如此。 在您编写的任何法语文档中(报告评论、PRD、跟踪器工单、裁决结果),属性/元素/角色名称及其值都是代码,而非散文 — 切勿翻译它们:
aria-live保持为aria-live(永远不要写成 « région live »),tabindex、alt、role="alert"、地标角色名称也是如此。引擎自己的法语目录遵循此规则;请与其保持一致。规范性标准词汇(RGAA 的措辞,例如 « lien d'évitement »)保留其官方法语形式。
参考库
先了解领域知识,再熟悉工具。阅读与您面临的问题相匹配的文档。
| 无障碍知识 | |
|---|---|
references/adjudication.md | 如何裁决引擎交给您的 52 个标准中的每一个 — 决策规则、何时 NA 是合理的、问题清单 |
references/naming.md | 可访问名称计算、2.5.3 label-in-name、使用 CSS 隐藏文本、命名图像/SVG/图表 |
references/widgets.md | ARIA APG 复合模式、键盘契约、焦点管理、SPA 路由变更、活动区域 |
references/forms-and-errors.md | 标签和说明、autocomplete 令牌列表、错误识别/建议/预防、冗余输入、可访问的身份验证 |
references/structure.md | 标题、地标、列表和 dl、简单与复杂表格、有意义的序列 |
references/media-and-motion.md | 字幕/音频描述/文字稿、指针手势、目标大小、方向、重排、减少运动 |
references/forbidden-patterns.md | 15 个反模式:错误 → 原因 → 原生修复 → 标准 |
references/focus-and-logic.md | 您负责的焦点/键盘标准,以及如何推理它们 |
references/criteria.md | 55 个标准:级别、可自动化类别、引擎规则、包映射(自动生成) |
references/rgaa-automation.md | RGAA 4.1.2:自动生成的 106 个标准 / 258 个测试矩阵、决定性规则、候选信号和静默策略 |
references/act.md | 引擎能够检测到什么 — 以及它明确无法检测到什么(自动生成) |
| 运行工具 | |
|---|---|
references/runbook.md | 可靠运行:唯一的方法、要使用的传输方式及其原因、以及一次通过的成本。在您为裁决付费之前,请先阅读此文档 |
references/claude-code-report.md | Claude Code 的详细发布路径:渲染范围、直接裁决、对抗性验证、Markdown + HTML + 每页证据 |
references/audit.md | 端到端的审计循环和规范性页面样本 |
references/judgment.md | 裁决 + 反驳工作列表、裁决词汇表、失败封闭模式 |
references/verify.md | check/verify 关卡 |
references/false-positives.md | 哪些发现仍可能是错误的,以及如何反驳它 |
references/rendered.md · references/automation.md | 审计生成的 HTML、捕获、钩子和 CI |
references/harnesses.md | 此工具的运行环境:Claude Code、Codex CLI、OpenCode 和 AGENTS.md 回退方案 |
references/orchestrators.md | 从工作流引擎 / 非 GitHub CI 驱动引擎:版本固定、六步流程、退出码、作为 JSON 输出的工单集(用于任何追踪器) |
references/ci.md | `--format sarif |
references/pages.md | 页面快照 + 每页标准网格 (pages),及其诚实规则 |
references/e2e.md | render --e2e:在您 Playwright/Cypress 运行时审计页面 |
references/devtools.md | dev:在您构建时的实时覆盖层,以及每页仪表盘 |
references/extension.md | 浏览器扩展:通过 side-car 审计您正在查看的页面 |
references/dynamic.md | scan 层级:运行时、探测、经过身份验证的页面 |
references/scale.md | 聚焦大型仓库的审计 |
references/fix.md · references/correction.md | 按优先级应用修复,且不引入回归问题 |
references/prd.md | 作为待办事项的审计器块(markdown) |
references/tickets.md | 将该待办事项列表作为工单提交:GitHub、GitLab、Jira,以及粒度级别 |
references/standards.md · references/packs.md · references/guidance.md | 国家/地区标准、编写包、实施指南 |
references/mcp.md | 作为规则引擎的标准:查阅标准而非回忆它 — 其编号的测试、它定义的术语、修复方案和工作计划。作为 MCP 工具和 std:// 资源提供,或通过 CLI 提供相同的数据 |
references/methodology.md | 状态、通过率、严重性、报告格式 |
references/cross-file.md | --graph:导入和跨文件规则 |
references/orchestration.md | 将裁决阶段分配给子代理 |
按场景选择
- “在 Claude Code 中生成详细的审计/报告” → 将当前活动的 Claude 会话用作审计器,关闭渲染和裁决相关的标准,质疑其主张,然后发布带日期的 Markdown 报告、可打印的 HTML 和附带证据的每页档案。请阅读
references/claude-code-report.md。这是交互式发布方案;完成后提供完整的交付物集。简洁摘要见下方的 CI 分支。 - “审计 / 合规性报告” →
node scripts/ultra11y.mjs audit … --json,然后执行report(综合表格 + 每个 NC 标准对应一个审计器合规块 — 与prd和tickets使用的块相同),然后执行check;阅读references/audit.md。 - “库渲染的代码(DSFR、MUI…)或
.vue/.svelte/.astro单文件组件 / 避免漏报” → 审计生成的 HTML,而不是源代码模板。最简单的方法:安装零接触的 capture 收集器(render --setup),这样您的测试将每个渲染的组件序列化到.ultra11y/captures目录(自动被摄取,发现结果归因于源组件;render --coverage和audit --require-captures跟踪盲区)。或者,使用render(构建→审计配方或 SSR 快照--scaffold),然后对输出执行audit,并使用scan进行计算后的渲染检查。单文件组件源代码的发现结果会被标记为preliminary(带有scope.sourceTemplate警告);阅读references/rendered.md。 - “发现结果看起来是错误的 / 组件的误报” → 引擎会自动抑制大多数组件的误报(插槽/属性注入的名称、组件子元素、动态绑定、条件标题),并将单文件组件/库源代码的发现结果标记为
preliminary;使用verify --apply来确认或反驳其余部分;阅读references/false-positives.md。 - “大型仓库 / 智能审计” → 聚焦:
--changed(git diff)、模板优先级排序、去重、--max-files;阅读references/scale.md。 - “跨文件分析(树 + 依赖),将 JSX/TSX 作为真正的 AST 处理” →
audit --graph解析导入并应用跨文件规则
…
[为便于翻译已截断]