---
share_worthy: yes
audience: UX, Dev
one_liner: 给「对比度太低」这类缺陷上阈值闸之前先量一遍设计侧的分布——本轮实测合法设计比 bug 还低，阈值结构上分不开两者。
evidence: 9881a215 · bb80c11d · docs/internal/backlog.md §INFRA-F145 (b)
---

# 阈值分不开 bug 与设计

> 2026-09-11 · 起因 = [[INFRA-F145]] 的修法候选 (b)「给 a11y 闸加禁用态对比度阈值」。
> **本篇只记可迁移的那部分**；落地物、读数、commit 在 [tracker](./design-spec-canonical-alignment-tracker.md)
> 与 [STATUS-CHANGELOG](../STATUS-CHANGELOG.md)，⛔ 这里不复述。

## 一句话

**给「某个量太低/太高」类缺陷上阈值闸之前，先量一遍那个量在「合法设计」里的分布。**
分布若与缺陷区间重叠，阈值就**结构上**分不开两者 —— 这时再谈阈值强弱、误报率、要不要 report-only
都是在错误的问题上用功。

## 这次的形状

owner 抓到一个禁用态按钮几乎不可读，实测对比度 **dark 1.66:1 / light 1.16:1**。
自然的修法是：让 a11y 闸对禁用元素单独算对比度、低于某阈值判红（WCAG 对非活动控件豁免，
所以阈值只能自己定）。entry 当时登记的参考点就是修完后的 **dark 2.34 / light 1.94**。

起工前把前置量了：manifest 里 `state=disabled` 且前景/背景都有确定 hex 的条目 **50 条 →
去重 12 个 (组件, 主题, 前景, 背景) 组合**，这些值全部来自 Figma、是**设计意图**：

| 对比度 | 组合 |
|--:|---|
| **1.52** | `Drop down List/Item` [light] |
| **1.61** | `select box/filled` · `input box/filled` [light] |
| 1.75 | `select box` · `input box` [dark] |
| 1.94 | `Button/light M`（本轮修完的那个） |
| 2.19 | `Drop down List/Item` [dark] |
| 2.34 | `Button/dark M`（本轮修完的那个） |
| 4.58 | `select box` · `input box` [dark] |
| 7.00 | `select box` · `input box` [light] |

**跨度 4.6 倍。而 bug 是 1.66，合法设计里有 1.52 和 1.61 —— 比 bug 还低。**

⇒ 任何抓得住 1.66 的阈值，都会同时把 `Drop down List/Item` 与两个 input/select 的浅色禁用态
判红。而那三处**不是缺陷**，是从 Figma 提取出来的设计值。

## 为什么值得单独记

因为**它不是「阈值定得不好」，是「阈值这个器械对这个目的无效」**。两者的处置完全不同：

- 前者 ⇒ 调参、加豁免、降成 report-only。
- 后者 ⇒ **换判据**。

这次换出来的判据是：**「某组件的禁用态 token 是否取自它自己那一族」**。
因为真病因不是「对比度低」—— 是那个按钮把 Checkbox/Radio/Slider 的 `--control-disabled-*`
控件形状 token 套到了 Button 上。同一个 1.66，若它来自 Button 自己那族的 token，就是设计决定；
来自别族，就是 bug。**判据必须看得见「来自哪一族」，而对比度这个量把这个信息丢光了。**

## 自查

接手任何「给某个数值上阈值」的提案时，动手前问三句：

1. **这个量在合法样本里的分布是多少？** 没量过就不要谈阈值。
   （⛔ 别拿「修完那一两个点」当分布 —— 那是 n=1，本轮 entry 登记的正是这种参考点。）
2. **缺陷区间与合法区间重叠吗？** 重叠 ⇒ 阈值无效，去找**能把两者分开的那个变量**。
3. **我要抓的那个缺陷，它的因果链上真正变化的是哪个量？** 本轮答案是「token 取自哪一族」，
   ⛔ 不是它解析出来的颜色对比度。

第 3 问与 [meta-rules 触发器 F §推荐自审](../../meta-rules.md) 第 ⑤ 问同源：
**这条推荐达成的是它声称的那个目的吗（不是「可行吗」）。**

## 一条配套的小纪律

量分布的量具**必须自带已知向量自测**。本轮对比度函数用 WCAG 的两个公开值钉住
（黑白 = 21.00 · `#777777` on white = 4.48），对不上就 `exit 3` 而不是给读数。
理由见 [[one-off-scripts-are-the-unreliable-part]]：本轮四次失误全在取证工具、产品侧零失误，
而工具失败的形态是**整齐的假象**而非报错 —— 一组看起来完全合理的对比度数字，
足以让人据此写出一条错误的闸。
