# 变异测试记录（判据有效性）

判据本身也会骗人：一个测试可能永远为绿。本文件记录**刻意植入的实现错误**与
观察到的结果——每条都实际应用过、跑过 `moon test`、然后还原。

复现方式：按「变异」列的描述改动对应代码，运行 `moon test --target wasm-gc`，
与「观察到的结果」列对比。表中数字是本机实测（wasm-gc 后端，8 位量化域）。

| # | 变异（改哪里、怎么改） | 判据应捕捉 | 观察到的结果 |
|---|---|---|---|
| 1 | v4 `mAB `/`mBA ` 的**矩阵段**按「8 字节类型头 + 矩阵」读（把 M 段签名后的 `para` 字节当成偏移） | `v4lut_wbtest.mbt` 节点判据、`v4lut_golden_wbtest.mbt` | **5 条测试变红**，节点值偏差 215–255 级 |
| 2 | 取消**曲线段的 4 字节对齐**（按绝对位置对齐改为相对位置） | 合成 14 字节曲线段的标签测试 | **1 条变红**（`test4.icc` 的段长都是 4 的倍数，只有合成样本能暴露） |
| 3 | 交换两个方向的**插值方式**（输入 LUT 用三线性、输出 LUT 用四面体，与 lcms2 相反） | `v4lut_wbtest.mbt`、`v4lut_golden_wbtest.mbt` | **2 条变红**，偏差 3–4 级 |
| 4 | 颠倒 `mBA` 的**阶段顺序**（B→Mat→M→CLUT→A 写成 A→CLUT→M→Mat→B） | `v4lut_wbtest.mbt` | **1 条变红**，偏差 255 级 |
| 5 | 忽略矩阵的**偏移项**（只用 9 个矩阵系数，丢掉 3 个偏移） | `v4lut_wbtest.mbt` | **1 条变红**，偏差 255 级 |
| 6 | PCS 为 `XYZ ` 时**解码**误按 u1Fixed16（应为 u1Fixed15） | `xyz_lut_wbtest.mbt` 编码常数判据 + 金标 | **3 条变红**，偏差 61–64 级（两处独立判据都命中） |
| 7 | PCS 为 `XYZ ` 时**编码**（逆方向）误按 u1Fixed16 | `xyz_lut_wbtest.mbt` | **1 条变红**，偏差 127 级 |
| 8 | 缺省的曲线段**返回空数组**而不是透传（`apply_curve_set`） | `v4lut_wbtest.mbt` | **3 条变红**（合成 XYZ profile 在满量程输入时输出 0） |
| 9 | 命名色条目步长 `named_color2_entry_base` 38 → 44（把 `ncl2` 的 PCS 当 `s15Fixed16Number` 的 12 字节） | `named_color_wbtest.mbt` 全部 5 条命名色用例 | **5 条变红**，报 `BadTagData(tag "ncl2": 声明 5 条命名色（每条 50 字节），但 tag 内只剩 220 字节）` |

## 这些变异为什么是有效的

- **每条都改在"看起来合理"的地方**：例如 #1 的"矩阵段有类型头"是 v4 LUT 里
  最容易想当然的假设（其它段都有类型签名），而规范里矩阵段**没有**；
- **有两条只有特定样本才能抓到**：#2 需要段长非 4 倍数的曲线（`test4.icc` 全部
  是 4 的倍数，所以额外合成了 14 字节曲线的标签样本）；#8 需要一条"缺省阶段"
  的真实路径。没有这些样本，变异会静默通过；
- **有一组变异单元测试抓不到，是第三方 oracle 抓到的（如实记录）**：命名色的第一版实现
  把 `ncl2` 的 PCS 当 `s15Fixed16Number` 写（12 字节/条），而**夹具生成器犯了同一个错**，
  于是生成与解析自洽、单元测试全绿——「自己和自己对拍」不构成验证。是 lcms2
  `cmsNamedColorInfo` 的逐条对拍暴露的：第 2 条起 `root=''`、`pcs=[0,0,0]`、设备坐标错位。
  上表 #9 是纠正之后补的**判别力证明**（改回 44 立刻 5 条变红），两者不可互相替代；
- **偏差量级可区分**：#1/#4/#5 是结构性错误（215–255 级），#3 是插值细节
  （3–4 级），#6/#7 是编码假设错误（61–127 级）。红测试的数量与偏差量级都与
  "改错了什么"对得上，而不是碰巧变红。
