基线（未注入）：PASS 81 ／ FAIL 0
✅ M1 死控件：注入(把 P2-01「低粉爆款」的实现掏空 —— 点它不再有任何反馈) ⇒ PASS 80 ／ FAIL 1 ｜ 报红且红在预期处（P2-01，视口 1440x900）
✅ M2 未登记的可点元素：注入(在页面上塞一个没写进交互清单的 data-act) ⇒ PASS 79 ／ FAIL 2 ｜ 报红且红在预期处（未登记的 data-act，视口 1440x900）
✅ M3 悬空声明：注入(清单里声明了一个页面上根本不存在的 ID) ⇒ PASS 79 ／ FAIL 2 ｜ 报红且红在预期处（声明了但页面里没有，视口 1440x900）
✅ M4 骨架漂移：注入(给 P3 多塞一个板块 —— ②段那份骨架是冻结的，这属于越界) ⇒ PASS 80 ／ FAIL 1 ｜ 报红且红在预期处（骨架与②段不一致，视口 1440x900）
✅ M5 对比度越界：注入(把 --ink-faint 换成偏白的灰，压到契约线以下) ⇒ PASS 80 ／ FAIL 1 ｜ 报红且红在预期处（对比度 --ink-faint，视口 1440x900）
✅ M6 点击无反馈（跳页不同步）：注入(把 go() 退回「只改 hash」的写法 —— 点完状态不动，自检应判它没反应) ⇒ PASS 79 ／ FAIL 2 ｜ 报红且红在预期处（驱动了没反应，视口 1440x900）
✅ M7 行高不齐（放开换行）：注入(删掉「行内每段不许换行」这条规则 —— 窄视口里文字一折行，行高就随文字长短乱跳) ⇒ PASS 79 ／ FAIL 2 ｜ 报红且红在预期处（行高不齐，视口 768x900）
✅ M8 密度退化（内衬变肥）：注入(把列表行内衬从 12px 加到 36px —— 行变肥，一屏就装不下 6 行了) ⇒ PASS 79 ／ FAIL 2 ｜ 报红且红在预期处（低于契约 6 行，视口 1440x900）
✅ M9 量尺寸时页面不在零点：注入(量 P1 之前先把页面滚下去 —— rect 取到的是相对视口的坐标，滚了之后 top 全变负，「一屏装得下几行」的减法就会凭空变大（这条守卫盯的就是它）) ⇒ PASS 80 ／ FAIL 1 ｜ 报红且红在预期处（被滚到，视口 768x900）
✅ M10 行分隔线被关掉：注入(把选择器退回成 `.list-row:first-child` —— 每行都包在 <li> 里，于是每行都是自己 <li> 的 first-child，整张表的分隔线一起消失（原型里修掉过的真缺陷，原样退回）) ⇒ PASS 80 ／ FAIL 1 ｜ 报红且红在预期处（行分隔线根本没画出来，视口 1440x900）
✅ M11 浮层没有遮罩：注入(去掉遮罩层 —— 「点层外空白关掉浮层」这条通道就没了) ⇒ PASS 72 ／ FAIL 9 ｜ 报红且红在预期处（没有遮罩，视口 1440x900）
✅ M12 关掉浮层后焦点不还回去：注入(把 closeLayer 退回「只清状态」的写法 —— 焦点会掉回 body，键盘用户就断了) ⇒ PASS 74 ／ FAIL 7 ｜ 报红且红在预期处（关掉后焦点没回到，视口 1440x900）
✅ M13 浮层多出一个中性关闭出口：注入(给「随手记」再加一颗 ×（多一个 X-close）—— 一个层两个中性出口会让用户找不着北，这条判据原先只数 .layer-close 类名，多出来的是同类，应当报红) ⇒ PASS 74 ／ FAIL 7 ｜ 报红且红在预期处（中性关闭出口 ＝ 2，视口 1440x900）

变异对照：13 / 13 通过
⇒ 13 处假病全部被自检抓住，且基线回绿：这套判据不是恒绿的。
