# 设计规格：让 TVU DS 规则被真正消费（而非"声明即摆设"）

- **日期**：2026-07-22
- **状态**：设计已批准，待写实现计划
- **性质**：跨消费面的规则执法机制重设（非新增规则）

## 问题陈述

owner 报告：用 claude.ai/design 基于两个 TVU DS 项目做出来的设计**默认不遵守设计系统规则**（实测症状：正文字体掉到 12px + 非 DS 字体；页面"非常不合理"，缺空态/错误态/边界态等）；而且用本仓库的 `design-walkthrough` 走查也**发现不了**这类问题。规则已经很多，却不触发——本质是仓库 `meta-rules.md §3` 的**反模式 #7「声明了 ≠ 被消费」**：规则写进文档，但生成端 / 走查端实际不加载、不跑它。

## 根因（分消费面，均已取证）

| 消费面 | 规则在不在 | 根因 |
|---|---|---|
| **Sync B `/design-sync`**（`406a39da`） | ❌ 规则语料根本没 ship | `list_files` 实测：只 ship 组件 `.d.ts/.html/.jsx/.prompt.md` + `_preview` + `styles.css` + `README.md`（来自 conventions.md）+ bundle。**无 SKILL.md、无 reference/ 目录、无 reference/04**。抽查 `Button.prompt.md` = 纯 props + 渲染示例，无跨切面规则。规则被默认"放在 Sync A" |
| **Sync A 手动 bundle**（`bfca04be`） | ✅ SKILL + reference 都在 | 未验证 claude.ai/design 是否把 SKILL.md 当"活指令"自动加载（owner 也不确定）。若非自动注入 → 靠 agent 读长文档 + 自觉执行 = 弱消费 |
| **走查 `design-walkthrough`** | ✅ 维度极多 | 整个为 **Figma mockup** 设计（node-id、`use_figma` probe、`audit:mockup-*` 机检跑 Figma 文件）。**无"审生成 HTML/CSS 的字号/token 遵守"维度** → claude.ai 产物的字体/硬编码问题不在射程内 |

字体特例：`variables.css` 只把字号/字族定义成 `:root` 自定义属性，**无任何把它们应用到元素的 base 规则**；bundle `styles.css` 也只 `@import` token。真实产品在 `App.vue` 根节点手动应用 base 字体（`playground/App.vue:50`），Claude Design 又没规则告诉 agent 这么做 → 掉到工具默认 12px（= `--font-size-tips`）。

## 设计原则

**执法按可靠性分层，越靠上越不依赖"agent 读没读"。** 一条规则的有效性 = 其最弱消费点的可靠性。不赌 claude.ai/design 会读长文档（该事实未确证）。不新增规则、不造第二真源——把已有真源在正确的通道里**可靠地消费**。

## 设计：5 层

### L1 · 默认即正确（correct-by-construction）— 最可靠
- 在导出的 `styles.css`（Sync A + Sync B 都 ship）注入 base 排版：
  ```css
  body { font: var(--text-style-body); font-family: var(--font-family-base); }
  ```
- **决策（owner）**：**只设 `font`，不设 `color`**——文本色当前应用正确，由各 Surface / 组件按主题处理，避免深色默认下浅色字落白底不可见。
- 落点：`scripts/export-claude-design-bundle.mjs` 的 `ROOT_STYLES` 常量（已改）。Sync B 的 `styles.css` 由 `/design-sync` 驱动产出——需确认驱动产的 styles.css 也带这条（见 L3 验证）。

### L2 · 非谈判 core（单一真源，两项目先读位都放）— 中等可靠
- 在 `docs/CLAUDE_DESIGN_RULES.md` 顶部加「§0 核心·先读」≤7 条打点清单，每条一句话 + 指回详细章节（**不造第二真源**）：token 不硬编码 / 正文 14px·12px=tips / 交付前枚举状态（空·加载·错误·边界·多角色）/ 用 canonical 组件不手搓 / 核渲染实况 / 深色默认不并排双主题 / 找资源查目录全集别按"用过的"凑。→ 进 Sync A 的 SKILL.md。
- 同一段精简 EN core 放 `.design-sync/conventions.md` 顶部 → 自动进 Sync B 的 README（**补掉 Sync B 无规则的洞，无需动驱动**）。
- 修 `scripts/export-claude-design-bundle.mjs` README 生成里 mockup 阅读路径漏掉 `reference/04`（状态完备性真源）的 bug——加进路径。
- 已并入本层的细化规则（前序会话已起草、待并入 §0 指向的详细章节）：#8 核渲染实况（§4）、字体 base 排版（§1）、状态完备性 gate（§4）、查漏元原则 #6（§4）。

### L3 · 不可绕过的 per-component 通道 — 强可靠
- **决策（owner）：做**（动驱动）。
- agent 用组件必读 `.prompt.md`；让驱动给每个生成的 `prompt.md` 注入一行 core 指针（如："⚠️ 组合前先过核心规则：token 不硬编码 · 正文 14px · 枚举状态（空/加载/错误）· 核渲染实况 · 用 canonical 组件"）。
- 落点：`.ds-sync/lib/emit.mjs`（`emitPerComponent` 的 `head` 组装处；实现时定位，非本 spec 初稿写的 `docs.mjs`——以 plan + 实现为准）。影响 35 个 prompt.md，走 `/design-sync` 重新生成 + 上传。

### L4 · 走查兜底覆盖输出面 — 兜底网
- 给 `skills/design-walkthrough/SKILL.md` 加一轴：审**生成 HTML/CSS 输出的 token & 排版遵守**——硬编码 `px`/`hex` vs `var(--*)`、正文 14px（非 12px）、字族 = DS。让兜底网覆盖 claude.ai 产物，不只 Figma。与现有"仅 Figma 机检"维度并列，page-type gate 决定何时触发。

### L5 · 并行实测（方向 2，owner 侧，非代码改动）— 校准
- owner 在两项目各跑一个零提示设计，观察实际遵守了哪些规则 → 反推真实消费通道，校准哪层在真正承重。结果回来后可能微调 L1–L4 权重。**不阻塞 L1–L4 落地。**

## 非目标（YAGNI）

- 不重写 `/design-sync` 驱动架构、不合并两个项目。
- 不给 claude.ai/design 产物做机检遵守闸（我们这边够不到其运行时）。
- 不把整份 SKILL + reference 语料复制进 Sync B（L2 的 core + L3 的 prompt.md 指针足够；全量复制 = 维护双份）。

## 涉及文件

| 层 | 文件 |
|---|---|
| L1 | `scripts/export-claude-design-bundle.mjs`（`ROOT_STYLES`，已改） |
| L2 | `docs/CLAUDE_DESIGN_RULES.md`（§0 core + 细化章节）、`.design-sync/conventions.md`（core EN 镜像）、`scripts/export-claude-design-bundle.mjs`（README 阅读路径修 reference/04） |
| L3 | `.ds-sync/lib/emit.mjs`（prompt.md 注入 core 指针；实现落点，非初稿的 `docs.mjs`） |
| L4 | `skills/design-walkthrough/SKILL.md`（新增生成代码 token/排版遵守轴） |

## 验证计划

- **仓库闸**：`pnpm test`（vue-tsc + vitest）绿；导出脚本改动后 `pnpm export:claude-design-bundle` 成功。
- **L1 亲验**：导出后 `styles.css` 含 `body{font:var(--text-style-body)…}`；Sync B 驱动产的 `ds-bundle/styles.css` 也含（get_file 远端 styles.css 核实）。
- **L2 亲验**：Sync A 远端 `SKILL.md` §0 含 core；Sync B 远端 `README.md` 含 core；README 阅读路径含 `reference/04`。
- **L3 亲验**：Sync B 远端任取 2–3 个 `*.prompt.md` 含 core 指针行。
- **CRITICAL（Sync B 每次同步必过）**：空-bundle 核验全绿（`[ignored-bare-import]`=0、`_ds_bundle.js` 多 MB、`customElements.define`≥1）。
- **L4 亲验**：walkthrough SKILL 新轴文本落地 + 一次真实 claude.ai 产物走查能命中字体/硬编码（可结合 L5）。

## 同步与提交

- 全部真源改动**并一个 commit** push master 双 remote（Gitea + GitHub）。
- **一次性同步两个项目**（避免多次对外写入）：`pnpm export` → **Sync A**（手动 bundle，targeted overwrite SKILL/README/styles）→ **Sync B**（`/design-sync` 驱动重跑 → CRITICAL 全绿 → 传 README/styles/prompt.md/anchor）→ 每步 get_file 亲验。
- finalize_plan 的 file-set 发出前贴给 owner 确认。
