# P2 · 扩展 rubric + 批量重测（验证 P0/P1 修复见效）— 2026-07-27

> 上游：[`2026-07-24-p0-systematic-gap-fixes.md`](./2026-07-24-p0-systematic-gap-fixes.md) §P2（owner 定为独立 session）。
> 起因：owner 让验证"用这两个设计系统设计产品时 AI 知不知道何时用哪个组件/字体/图标/spacing" + UX 流程；P0/P1 已 ship，P2 = 量化验证缺陷率是否下降。
> 本文件是 P2 实验 SoT + 可复跑锚点。跨 session 续跑读本文件 + 看 `scratch/ux-test/p2/` 产物。

## owner 决策（2026-07-27）

- **规模**：全量 = **3 任务 × 3 环境(regime) × n=5 builder + 3 盲评/产物**。
- **Before 臂**：owner 交我判断 → 选 **真·对称 A/B**（长远可复用 + 效度覆盖全 7 类缺陷 + 盲评可信）。修正上一轮把 after-only 当 #1 的排序错误（`lead-with-robust-not-cheapest`）。

## 效度设计

- **自变量**：arm ∈ {before=`a21a154f`(P0/P1 全部之前) / after=HEAD} × regime ∈ {repo / curated / driver}。
- **重复**：n=5 → 3 任务 × 3 regime × 2 arm × 5 = **90 builder cell**。
- **主指标（缺陷判定）= builder 结构化 self-report**：每 builder 返回其关键角色的组件选择（confirmDialog / table / navBadge / tabSwitch / notifAlertBtn / icons 的枚举值），D1–D6 由枚举值确定性映射。before 臂结构性约束（契约缺 cell/change/badge/Icon）使 builder 无法谎报不存在的能力 → self-report 可信。
  - **完整性交叉核** = `probe-defects.mjs`（跑 raw HTML，复用 P0-2 linter + alias-aware 组件探针）：验 self-report 未谎报（如报 tvuds-table-cell 但源码无 → 冲突）。**冲突人工裁定**。D7(未约束 svg) 由探针客观判（self-report 不覆盖）。
  - **为何不纯静态探针**：fixture 实证纯探针风格脆弱——builder 写 `h('nav')`/`h('table')`(React.createElement) 时字面标签规则漏；注释含组件名致 FP。self-report 风格无关。
- **次指标（盲评面板）**：3 评审/产物盲评 L1–L4 rubric 质量，盲于 arm，取中位。
- **不 render / 不需可运行 bundle**：缺陷是 authoring 选择，源码 + self-report 可判；before builder 靠读 pre-fix 契约被自然约束。

### 3 环境(regime) 定义（可从 git 任意提交复现；诚实映射 n=1 三环境）

| regime | ≈n=1 | 物料 = builder 能读到的 | 测什么 |
|---|---|---|---|
| **repo** | repo | 全源：`src/components/*/*.vue`(defineProps) + `src/canonical/*` + 全 docs + `.design-sync/` + `dist/icons` | 最富信息下的天花板 |
| **curated** | Sync A | 纯人策展 prose：`CLAUDE_DESIGN_RULES.md` + `figma-component-catalog.md` + `mockup-conventions.md`(相关段) + `domain-tvu.md` + `variables.css` + icon 清单。**无类型契约** | prose 够不够 |
| **driver** | Sync B | per-组件类型契约+prompt：`.design-sync/previews/*.tsx` + 生成的 `.d.ts`/`.prompt.md`（HEAD 有）/ 源级(before) + `.design-sync/conventions.md` + `reference/04-design-process` | 类型契约够不够 |

> 诚实边界：这是 3 regime 的**可复现重建**，非字节级重放 2026-07-24 claude.ai 上传的 Sync A/B bundle。映射足够代表"人策展 prose vs 类型契约 vs 全源"三种引导密度。

## 缺陷分类学（P0/P1 靶向 = 主因变量；n=1 实测锚定）

| # | 缺陷 | 探针判据（静态） | n=1 | 修复 | before 预期 |
|---|---|---|---|---|---|
| D1 | 确认弹窗用 PopupBox（应 Notification form=dialog）| 源含 PopupBox + 确认/取消/删除/停止按钮对 | repo 1/3 | P0-2 linter + P1-2 | 概率性(prose 已在，仍违) |
| D2 | 手搓 table（DS Table 装不下 pill/按钮）| 有 `<table>`/flex 行网格承载 pill/button 而非 `TvuDS.Table` + `columns[].cell` | **3/3** | P0-1 cell 描述符 | ~100%(结构性:契约无 cell) |
| D3 | MenuList 无 badge → workaround | 导航计数用旁挂 PillCounter/自画而非 MenuList item `badge` | syncA | P1-4 | ~100%(契约无 badge) |
| D4 | Tab change 不跨 CE → 退回 Button | tab 切换用 Button 组代替 `TvuDS.Tab`+change | syncB | P1-3 | ~100%(无 change 事件) |
| D5 | Notification alert okText/confirmText 混淆 | alert form 传 confirmText（应 okText）| syncB | P1-2 docs | 概率性 |
| D6 | 无公开 Icon → 内联/自画 SVG | 内联 `<svg>` 而非 `TvuDS.Icon`/registry | **3/3** | P1-1(repo 已 ship;SyncA/B 待重编译) | ~100%(无公开 Icon) |
| D7 | 未约束内联 SVG（撑爆）| `<svg>` 无 width/height 且无 CSS 尺寸 | repo 1/3 | P0-2 linter rule2 | 概率性 |

> **关键预期洞察**：P0-2 linter（D1/D7 的机器闸）只在 **repo**(有 git) 生效；**curated/driver**(claude.ai 无 git) 的 D1/D7 修复只有强化 prose。实验应显式暴露"机器闸仅护 repo 环境"这条。

## 扩展 rubric（4 层，评审盲评次指标用；真源派生）

- **L1 · M49 设计质量合同**（`design-process.md` §M49，7 维）：Baseline/Delta · Semantic Pattern · Feedback UI Inventory(toast/inline-alert/modal-notification/popover-hint 同源) · UX(一致/可用/易用/可达) · Simplicity · Content · +F1.6 组件化合规。
- **L2 · 5-stage×5-lens 旅程**（`design-process.md` §Stage 0.5）：Awareness/Consideration/Pairing/Daily Ops/Troubleshoot × Actions/Touchpoints/Thoughts/Pain/Opportunities → 重点 **state-completeness**(loading/empty/error/长文本/离线 全链路)。persona 集 = SRE/PM/L2 Support/CFO。
- **L3 · WCAG**：对比度 / 键盘焦点 / ARIA role / 点击区 ≥24–44px。
- **L4 · Nielsen 十启发**：状态可见/现实匹配/用户控制(不可逆 Stop 撤销)/一致/错误预防/识别优于回忆/灵活/极简/错误恢复/帮助。

评分：每维 0–2（0=违反/缺失,1=部分,2=达标），盲于 arm，3 评审取中位。

## 3 任务（覆盖 D1–D7）

1. **列表台** = n=1「直播源管理」verbatim 复用（可比性）：120 源 + 筛选栏 + 行状态 pill + 行操作(预览/停止) + 不可逆停止(确认+结果反馈) + 分页 + loading/empty/error + 超长源名 + 告警导航角标。→ D1/D2/D3/D6/D7。
2. **表单流** =「新建推流目标配置」多步表单：FormItem+Input/Select/Switch/Radio + 校验(APID-02) + Steps + Tab 分段 + 保存二次确认 + success/error 反馈。→ D4/D5/D6 + FormItem/校验。
3. **数据可视化** = 监控仪表盘：KPI stat tiles + Chart(echarts) + 状态分布 + 趋势 + 告警面板 + 下钻筛选。→ Chart + D6(tile 图标) + D2(若含表) + 一致性 + Troubleshoot 阶段。

## 执行结构

1. **组装 6 物料包** → `scratch/ux-test/p2/materials/<regime>__<arm>/`（`git show a21a154f:` / HEAD 文件复制，零 build）。
2. **确定性缺陷探针** `scratch/ux-test/p2/probe-defects.mjs`（扩 P0-2 linter + 组件用法探针）→ 对 90 产物输出 D1–D7 flag JSON。**我跑，非 agent。**
3. **Workflow**（外包，owner 授权 + 全量 opt-in）：
   - phase Build：90 builder（agentType 通用），每个只喂其 cell 的物料包路径，Write HTML 到 `scratch/ux-test/p2/out/<task>__<regime>__<arm>__n<i>.html`，返回 {path, 自述组件用法}。
   - phase Review：每产物 3 盲评（不告知 arm）→ L1–L4 打分 schema，取中位。
4. **分析** `scratch/ux-test/p2/analyze.mjs`：合并探针(主) + 盲评中位(次) → 缺陷率 before→after 逐 D 逐 regime + rubric 质量 delta → 报告 `scratch/ux-test/p2/RESULT.md`。

## 纪律（本 session 必守）

- 批量测评走 Workflow 外包，主线只保结论（memory `批量任务走 Subagent`）。
- DesignSync 只主 session，本任务不碰（P2 不需要）。
- **Eduardo `019dfb04` 绝不碰**。
- 并行 worktree `.claude/worktrees/apid-01-table-datagrid/` 是别 session（APID-01），不动。
- subagent 报"完成"须有可复核证据：产物文件 ls 亲验存在 + 探针确定性判据（memory `verify-subagent-artifacts-exist` / `Subagent 完成声明必须有可复核证据`）。

## 状态

- [x] rubric 派生 + 缺陷分类学锚定 + pre-fix 基线 `a21a154f` 确认
- [x] 组装 6 物料包（保真度亲验：before 缺 cell/change/badge/Icon，after 有）
- [x] 确定性探针（fixture 验证 → 定 self-report 主判 + 探针交叉核）
- [x] Workflow 首轮全量启动 → **中途撞 session 限额**（23/90 builds 完成，评审 0）。args.smoke 被 harness 字符串化 → 直接全量（非 smoke）。
- [x] 分析（`scratch/ux-test/p2/RESULT.md`，29 cells self-report，t1 三 regime × before/after 齐，仅缺 driver-after n5=c029 的 self-report — 其 HTML 已落盘，缺陷率按 4 样本判）
- [x] **盲评（次指标）DESCOPE**（owner 2026-07-27 决策）：结论"给 AI 实际用，不是给人看的报告" → 主观质量盲评对 AI 消费无价值，砍掉。build 侧 self-report（AI 实际怎么选组件）已是"AI 会不会正确用"的直接证据。→ 90 盲评 + c029 rebuild 的 review workflow 已启动后即停（`wf_5022f867-cf8` / task `wgal77r2v` stopped）。
- [x] **t1 主结论已定（= 可靠性测试结果）**：见下表。类型契约(driver/repo) 对新能力可靠、纯 prose(curated) 对新能力不可靠。
- [ ] **t2/t3 也 DESCOPE 为按需**：D4(Tab-change/P1-3) 若要验，读代码+测试确定性验更省更准，不必跑 30-cell A/B；t3 纯扩样本，最低价值。留 owner 判是否要。
- [x] **P2b 实测真实 bundle A/B（2026-07-27，owner 追加）→ 修正下方 P2 子集结论**：见 `scratch/ux-test/p2b/RESULT.md` + 本文件末 §P2b。真实 Sync A ≈ Sync B（D2/D3/D6 两臂全 0%）；P2 的"curated 漏 / 契约胜"是**子集假象**。
- [ ] **生成器缺口（LOW，backlog 候选，非现在做）**：driver `.d.ts` 生成器把嵌套对象数组类型（`TableColumns`/`MenuListItems`）拍平成空壳、`.prompt.md` 只给 happy-path 示例 → 深层能力（column `cell` / item `badge` / 事件 prop 名）靠模型推。**必要性低**（Opus 级模型推得对）；仅当喂弱模型 / 高保真不容猜错时才修（展开嵌套类型 + 富示例）。**别顺手滑进去做**（scope-creep）。

## t1 主结果（列表台，self-report 主判，build 侧 29/30 完成，2026-07-27）

> build 侧 3×2 矩阵基本齐（仅缺 driver-after n5=c029）。**盲评（次指标）本轮 0 数据**（撞限额，reviews 无 id 无法配对）→ 留后续窗口。

| 缺陷 | repo b→a | curated b→a | driver b→a | 判读 |
|---|---|---|---|---|
| D2 手搓表格 | 5/5→0/5 | 1/5→0/5 | 5/5→0/4 | P0-1 cell 描述符：类型契约(repo/driver)完全采纳 |
| D3 nav badge 旁挂 | 5/5→0/5 | 5/5→**4/5** | 5/5→0/4 | P1-4 MenuList badge：repo/driver→0；**curated(prose) 仍 80%** |
| D5 alert confirmText | 0(n/a) | 5/5→0/5 | 0 | P1-2 docs：curated 生效 |
| D6 内联/文字图标 | 1/5→0/5 | 4/5→**3/5** | 0→0 | P1-1 公开 Icon；curated 仍退化 60% |
| D1/D4/D7 | 0 | 0 | 0 | t1 未强触发（D1 prose pre-fix 已生效；D4 需 t2 表单）|

**核心结论（量化印证 P0 计划核心洞察）**：机器可读契约（repo/driver）传达新能力 → builder 采纳 → 能力缺口缺陷 100%→0%；**纯 prose（curated）传达差 → 缺陷残留**（D3 修后仍 4/5、D6 仍 3/5）。→ "缺的是执行保障（机器契约/闸）不是 prose" 得到数据支持。
**方法学副证**：9 处 self-report↔探针冲突全为探针假阴（React.createElement 产物无字面 `<table>`，探针漏 D2）→ 纯静态探针会整段漏掉 D2；self-report 捕到 100% 手搓 → **self-report 主判决策正确**。

**可靠性结论（P2 子集版 — ⚠️ 已被下方 §P2b 真实 bundle 实测修正，勿单独引用）**：after 侧残留缺陷 —— repo/driver 全 0%；curated 仅 D3 80% + D6 60% 仍漏。**但这是 P2 子集造成的假象**：P2 driver 包塞了 `.vue` 源码（含完整类型）、P2 curated 缺了真实 Sync A 有的卡片画廊 → 人为拉大了差距。真实 bundle 上两者等价（见 §P2b）。保留本段仅作方法学留档。

---

## §P2b 实测（真实 bundle 头对头，2026-07-27）— 结论真源

> 完整数据 = `scratch/ux-test/p2b/RESULT.md`。t1，n=3/臂，self-report 主判 + probe 交叉核。材料 = 真实 `ds-bundle/`(Sync B：卡+per-组件契约) vs `sync-a/` 镜像(Sync A：同款卡+相同 4 reference，无契约)。两臂唯一变量 = 契约层。

**缺陷率**：D2/D3/D6 **两臂全 0/3**。真实 Sync A ≈ Sync B，无可测差异。（probe 一度报 5/6 D3 = 假阳，grep 实证 6/6 都把 `badge` 挂 MenuList item 上。）

**机制发现（比缺陷率重要）**：两臂共享的 reference prose **没写** MenuList item `badge` 字段 / Table `cell` 描述符，Sync B 独有的 `.d.ts`/`.prompt.md` **也没教**（嵌套类型空壳 + happy-path 示例）。但 6 个 builder **全部正确推断**出这些深层 API（`badge:{label}` / `cell:{kind}` 对照真源均正确）。**= 深层能力靠模型「推」对，不是 bundle「教」的。**

**术语澄清（避免误读）**：D3 讲的是 **MenuList 列表项的 `badge` 字段**（P1-4，内嵌未读角标，底层复用 canonical **Badge 组件**），**不是** "Badge 组件缺失"——Badge 组件一直在库里。D3 缺陷 = 未读数是挂在 MenuList item 的 `badge` 字段上，还是在导航旁另搭外挂计数器。

**对「维护哪个」的结论**：
1. **今天 Sync A ≈ Sync B**，输出无差，强模型把两个 bundle 都没明写的深层 API 都桥接了。
2. **真瓶颈正交**：两条生成管线都把深层能力丢在浅层契约外，靠模型推。强模型 OK，弱模型/高保真不可靠。
3. **长期押 Sync B（driver 契约）**——非今天更好，而是格式有升级空间（修生成器 → 契约保证）；Sync A 卡+prose 格式装不下类型契约，天花板 = 强模型推得对。
4. **最高杠杆（不管留哪个）= 修 driver 生成器**（上方 backlog 候选，**LOW**）。

**诚实边界**：n=3/臂、单任务 t1、单模型（Opus 级）。样本小；换弱模型时契约层价值才显现。
