# DS 规则消费重设 Implementation Plan

> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.

**Goal:** 让 TVU DS 规则在 claude.ai/design 生成端（两条同步路径）+ 走查端被真正消费，而非"声明即摆设"（反模式 #7）。

**Architecture:** 执法按可靠性分层——L1 默认即正确（styles.css）、L2 非谈判 core 进两项目先读位、L3 per-component prompt.md 注入 core 指针（动驱动）、L4 走查加生成代码遵守轴。不新增规则、不造第二真源，把已有真源在正确通道可靠消费。

**Tech Stack:** Node ESM 脚本（导出脚本 + `.ds-sync` 驱动 lib）、Markdown 规则文档、DesignSync 工具（对外上传）。

**真源 spec：** [docs/superpowers/specs/2026-07-22-ds-rule-consumption-design.md](../specs/2026-07-22-ds-rule-consumption-design.md)

## Global Constraints

- **全部真源改动并入一个 commit**（owner 指定），push master **双 remote**（Gitea `origin` + `github`）；GitHub 常报 phantom `remote rejected`，以 `git ls-remote` 实际 sha 为准。
- **一次性同步两个项目**，避免多次对外写入。对外上传前把 `finalize_plan` 的 file-set 贴 owner 确认。
- **CRITICAL（Sync B 每次同步必过）**：空-bundle 核验全绿——build 日志无 `[ignored-bare-import]`、`_ds_bundle.js` 多 MB、`grep -c customElements.define ds-bundle/_ds_bundle.js` ≥1。NOTES 记录曾两次 ship 成空 bundle。
- **不造第二真源**：core 是对已有章节的浓缩指针，细节仍住 §1–§5 / reference/*。
- 规则文档均为 `.md`/`.mjs`，非视觉改动 → pre-commit 不需 `VISUAL_COMMIT_APPROVED`；但 husky 跑 `vue-tsc + vitest`，须全绿。
- **已在工作树的草稿改动**（未提交）：`docs/CLAUDE_DESIGN_RULES.md`（§1 字体 base 排版 + §4 #8 核渲染实况 + §4 状态完备性 gate + §4 查漏元原则 #6）、`.design-sync/conventions.md`（#8 + 字体 base 段）、`scripts/export-claude-design-bundle.mjs`（`ROOT_STYLES` 注入 `body{font}`，只 font 不 color）。这些是 L1/L2 细节层，本计划在其之上补 §0 core 等；执行时一并纳入最终 commit。

---

### Task 1: L2 — §0 核心·先读 进 SKILL 源 + conventions 镜像

**Files:**
- Modify: `docs/CLAUDE_DESIGN_RULES.md`（在 frontmatter 后、现「## 0. 两条铁律」处，前置「核心·先读」清单；两条铁律降为 §0 内子节）
- Modify: `.design-sync/conventions.md`（顶部 intro 段后、`## Setup & theming` 前，加精简 EN core）

**Interfaces:**
- Produces: `CLAUDE_DESIGN_RULES.md` §0 打点清单（→ 打进 Sync A `SKILL.md`）；`conventions.md` core 段（→ 打进 Sync B `README.md`）。Task 6 上传时核实。

- [ ] **Step 1: 改 `docs/CLAUDE_DESIGN_RULES.md` 的 §0**

把现「## 0. 两条铁律（高于一切）」整段替换为：

```markdown
## 0. 核心 · 先读（非谈判，违反任一条 = 交付缺陷，停下重做）

> 最常被违反、后果最重的几条。每条指向下面的详细章节;先把这张清单过一遍再动手。

1. **token 不硬编码**:颜色 / 字号 / 间距 / 圆角一律 `var(--*)`,绝不写 `#hex` / `12px` 字面量。→ §1
2. **正文默认 14px + DS 字族**:`styles.css` 已给 `body` 设 `font: var(--text-style-body)`(14px, `--font-family-base`);你的布局容器另设字号时用 `--font-size-body`(14px),**12px = `--font-size-tips` 仅次要 / 提示文字**;别把文字留给工具 / 浏览器默认。→ §1
3. **用 canonical 组件,不手搓等价物**:logo / 菜单 / 对话框 / 表格 / 表单 / 顶栏账号菜单都有库组件,别用 `div`+CSS 拼。→ §3
4. **交付前枚举状态**:每个 first-class 实体过一遍 空 / 加载 / 错误 / 边界 / 多角色,**漏态 = 缺陷,不是"以后再补"**。→ §4
5. **用了组件 ≠ 渲染对了**:亲看渲染结果,核 slot 填充 / 子元素真渲染 / 图标资源解析。→ §4
6. **深色默认,不并排双主题**:dark 是 `:root`,light 用 `[data-theme="light"]`,同一时刻只展示一个主题。→ §1
7. **找资源查目录全集**:找组件 / 图标 / token 查 `reference/01` / `icon-keys-index` / `tokens/variables.css` 全集,别按当前页"用过的"凑清单(必漏已发布未用的)。→ §2 / §4

### 0.1 铁律（高于一切）

1. **Figma 是真源**。组件的视觉（颜色 / 间距 / 尺寸 / 圆角 / 变体）以已发布库为准；设计稿用库组件,不自画形状拼凑已有组件。出处:`reference/03-mockup-conventions.md`、`reference/01-figma-component-catalog.md`。
2. **不按"行业惯例"自由发挥**。组件怎么用、什么场景用哪个、交付格式以本系统文档为准;没覆盖的向用户确认,不凭通用设计常识补全。出处:`reference/02-component-affordances.md`。
```

- [ ] **Step 2: 改 `.design-sync/conventions.md` 顶部加 core**

在第一段 intro（`These components are React wrappers…`）之后、`## Setup & theming` 之前插入：

```markdown
## Core rules — read first (non-negotiable)
Violating any of these is a delivery defect, not a nicety:
1. **Never hardcode** — colors/font-size/spacing/radius all via `var(--*)`, never literal `#hex` / `12px`.
2. **Body text defaults to 14px + the DS font** — `styles.css` sets `body { font: var(--text-style-body) }`; on your own containers use `--font-size-body` (14px). **12px = `--font-size-tips`, secondary/hint text only.** Never leave text to the tool/browser default.
3. **Use canonical components, never hand-build equivalents** — logo, menu, dialog, table, form, after-login account menu all have components.
4. **Enumerate states before delivering** — empty / loading / error / edge / multi-role for every first-class entity; a missing state is a defect.
5. **Using a component ≠ rendering it right** — verify slots filled, children actually paint, icon refs resolve.
6. **Dark is default; never show both themes at once.**
7. **Enumerate resources from the full catalog, not from what's already used** — look up the component/icon/token registry, don't infer availability from the current page.
```

- [ ] **Step 3: 验证**

Run: `grep -c "核心 · 先读" docs/CLAUDE_DESIGN_RULES.md && grep -c "Core rules — read first" .design-sync/conventions.md`
Expected: 各 `1`。再 `grep -n "0.1 铁律" docs/CLAUDE_DESIGN_RULES.md` 确认铁律保留。

---

### Task 2: L1 + L2 — 导出脚本 base styles（已改）+ README 阅读路径修 reference/04

**Files:**
- Modify: `scripts/export-claude-design-bundle.mjs`（`ROOT_STYLES` 已注入 `body{font}`,本任务确认；`generateReadme` 的 mockup 阅读路径加 `reference/04`）

**Interfaces:**
- Consumes: 无。
- Produces: 导出的 `styles.css` 带 base 排版;`README.md`「画设计稿 / mockup」路径含 `reference/04`。

- [ ] **Step 1: 确认 `ROOT_STYLES` 已含 base 排版（已改）**

Run: `grep -A6 "const ROOT_STYLES" scripts/export-claude-design-bundle.mjs`
Expected: 含 `body {` + `font: var(--text-style-body);` + `font-family: var(--font-family-base);`,**不含 `color:`**。

- [ ] **Step 2: 修 README mockup 阅读路径（约 line 247）**

把 mockup 那行的 `… → \`03\`（交付规范）→ \`icon-keys-index\`（图标）…` 改为在 `03` 后插入 `04`：

```
→ \`03\`（交付规范）→ \`04\`（设计流程 + 状态完备性枚举）→ \`icon-keys-index\`（图标）
```

- [ ] **Step 3: 重导出并验证**

Run: `pnpm export:claude-design-bundle && grep -A6 "^body" /Users/nancy/Documents/AICoding/claude-design-bundle/styles.css; grep -n "04.*状态完备性" /Users/nancy/Documents/AICoding/claude-design-bundle/README.md`
Expected: 导出成功;bundle `styles.css` 含 `body{font:var(--text-style-body)…}`;README mockup 路径含 `04`。

---

### Task 3: L3 — 驱动给每个 prompt.md 注入 core 指针

**Files:**
- Modify: `.ds-sync/lib/emit.mjs`（`head` 组装处，约 line 347 的 one-line reminder / line 405 的 `const head = …`）

**Interfaces:**
- Consumes: 无。
- Produces: 每个 `<Name>.prompt.md` head 带一行 core 指针（→ Sync B 35 个 prompt.md）。

- [ ] **Step 1: 读 `.ds-sync/lib/emit.mjs` 340–410 确认 `head` / `providerNote` 结构**

Run: `sed -n '340,410p' .ds-sync/lib/emit.mjs`
（确认 `const head = \`${c.name} from ${PKG}. Use via …${providerNote}${kw}\n\`;` 的确切写法）

- [ ] **Step 2: 加 CORE_POINTER 常量并追加到 head**

在文件顶部常量区（如 `DOC_BODY_CAP` 附近，若在 emit.mjs 无则就近）加：

```js
// 每个 .prompt.md head 的核心规则指针 —— agent 用组件必读 prompt.md,这是最强消费通道(L3)。
const CORE_POINTER = '⚠️ 组合前先过核心规则(详见 README / SKILL §0):token 不硬编码 · 正文 14px(12px=tips) · 交付前枚举状态(空/加载/错误/边界) · 用 canonical 组件不手搓 · 用了组件≠渲染对了(亲核渲染实况)。';
```

把 `head` 模板追加一行（在 `${providerNote}${kw}\n` 之后）：

```js
const head = `${c.name} from ${PKG}. Use via \`window.${GLOBAL}.${c.name}\` (bundle loaded from the root \`_ds_bundle.js\`).${providerNote}${kw}\n\n${CORE_POINTER}\n`;
```

- [ ] **Step 3: 验证（走驱动重生 prompt.md）**

在 Task 6 的 `/design-sync` 驱动 build 后验；或单独跑 build 阶段后：
Run: `grep -l "组合前先过核心规则" ds-bundle/components/general/*/*.prompt.md | wc -l`
Expected: `35`（全部 prompt.md 带指针）。

---

### Task 4: L4 — 走查加"生成代码 token / 排版遵守"轴

**Files:**
- Modify: `skills/design-walkthrough/SKILL.md`（在 §5.8 视觉质量轴附近新增一节，或并入 §4 anti-pattern 后的固定轴）

**Interfaces:**
- Produces: 走查报告新增一轴（生成 HTML/CSS 输出面）。

- [ ] **Step 1: 读 `skills/design-walkthrough/SKILL.md` §5.7/§5.8 定位插入点**

Run: `grep -n "5.7\|5.8\|视觉设计质量轴" skills/design-walkthrough/SKILL.md`

- [ ] **Step 2: 新增「§5.9 生成代码遵守轴（claude.ai/design HTML/CSS 输出面）」**

插入（page-type 为"claude.ai 生成代码 / HTML"时触发；纯 Figma 交付物判 N/A）：

```markdown
## 5.9 生成代码遵守轴（固定层 — 覆盖 claude.ai/design HTML/CSS 输出,非 Figma）

> 走查对象是 claude.ai/design 生成的 HTML/代码时必跑（纯 Figma mockup 判 N/A）。Figma 机检(`audit:mockup-*`)对代码产物不适用,本轴补上。亲取渲染 + 读生成 CSS 核:

| 维度 | check | 判定 |
|---|---|---|
| **G1 字号/字族** | 正文 = `--font-size-body`(14px)/`--text-style-body` + `--font-family-base`;无裸 12px/非 DS 字体(12px 只该出现在 tips) | ✅ / ❌ |
| **G2 token 遵守** | 颜色/间距/圆角走 `var(--*)`;grep 生成 CSS 无 `#hex`/裸 `px` 字面量(除 0/1px 边框等) | ✅ / ❌ |
| **G3 组件真用** | 关键控件用 DS 组件(非 div+CSS 仿),且渲染实况对(slot 填充/图标解析,见 §4 #8) | ✅ / ❌ |
| **G4 状态覆盖** | 空/加载/错误/边界态有表达(见 §4 状态完备性 gate) | ✅ / ❌ |

> 依据:2026-07-22 根因——claude.ai/design 产物默认不遵守 DS 规则,走查原只覆盖 Figma、抓不到字号/硬编码。真源 spec `docs/superpowers/specs/2026-07-22-ds-rule-consumption-design.md`。
```

- [ ] **Step 3: 验证**

Run: `grep -c "5.9 生成代码遵守轴" skills/design-walkthrough/SKILL.md`
Expected: `1`。

---

### Task 5: 合并 commit + push 双 remote

**Files:** 上述全部（Task 1–4 + 已在工作树的草稿）。

- [ ] **Step 1: 过一遍 diff**

Run: `git status -s && git diff --stat`
Expected: 改动限于 `docs/CLAUDE_DESIGN_RULES.md`、`.design-sync/conventions.md`、`scripts/export-claude-design-bundle.mjs`、`.ds-sync/lib/emit.mjs`、`skills/design-walkthrough/SKILL.md`。

- [ ] **Step 2: 一个 commit**

```bash
git add docs/CLAUDE_DESIGN_RULES.md .design-sync/conventions.md scripts/export-claude-design-bundle.mjs .ds-sync/lib/emit.mjs skills/design-walkthrough/SKILL.md
git commit -m "feat(design-rules): make DS rules consumed not declared (L1-L4)"
```
（message 尾加 `Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>`。pre-commit vue-tsc+vitest 须全绿。）

- [ ] **Step 3: push + 核实**

Run: `git push origin master`,然后 `git ls-remote <gitea> -h refs/heads/master` 与 `git ls-remote <github> -h refs/heads/master` 均 = 新 sha（GitHub phantom reject 不算失败,以 ls-remote 为准）。

---

### Task 6: 一次同步两个项目（attended）+ 亲验

**Files:** DesignSync 上传（Sync A `bfca04be-9783-4eb5-b754-37b04a6c35ef` / Sync B `406a39da-1681-4edf-ae26-826cf3c33c9c`）。

- [ ] **Step 1: 重导出 Sync A bundle**

Run: `pnpm export:claude-design-bundle`（README 会带新 commit sha）。记录变更文件（预期 SKILL.md + README.md + styles.css）。

- [ ] **Step 2: Sync A finalize_plan 前把 file-set 贴 owner 确认，再 write_files**

file-set（localDir = `/Users/nancy/Documents/AICoding/claude-design-bundle`）：`SKILL.md`、`README.md`、`styles.css`（targeted overwrite，不动策展 components/mockups/versions）。

- [ ] **Step 3: get_file 核实 Sync A**

`SKILL.md` §0 含 core;`README.md` mockup 路径含 `04`;`styles.css` 含 `body{font:var(--text-style-body)…}`。

- [ ] **Step 4: Sync B 前置 + 驱动**

`cp src/tokens/variables.css react-pilot/ds-sync/tokens.css` → `cd react-pilot && ./node_modules/.bin/tsc -p tsconfig.dts.json`（源未变可跳,稳妥起见跑）→ 确认 `entry.tsx` `__tvu_wc_keepalive` 在。fetch 远端 `_ds_sync.json` → `.design-sync/.cache/remote-sync.json`（先 Read 该文件再 Write,避免 write 前未读报错）。驱动：
```
node .ds-sync/resync.mjs --config .design-sync/config.json --node-modules react-pilot/node_modules --out ./ds-bundle --remote .design-sync/.cache/remote-sync.json
```

- [ ] **Step 5: CRITICAL 空-bundle 核验（必过）**

`ds-bundle/.resync-verdict.json` `ok:true`;build 日志无 `[ignored-bare-import]`;`grep -c customElements.define ds-bundle/_ds_bundle.js` ≥1 且多 MB。Task 3 的 prompt.md 指针核：`grep -l 组合前先过核心规则 ds-bundle/components/general/*/*.prompt.md | wc -l` = 35。

- [ ] **Step 6: Sync B finalize_plan（file-set 贴 owner）+ 上传**

预期变更：`README.md`（core）、`styles.css`（base 排版）、35 个 `*.prompt.md`（core 指针）、`_ds_sync.json`（anchor 刷新）。以驱动 `.sync-diff.json` 实际变更集为准;`_ds_bundle.js`/`.css` 若 hash 变也带上。

- [ ] **Step 7: get_file 核实 Sync B**

远端 `README.md` 含 core;`styles.css` 含 base 排版;任取 2–3 个 `*.prompt.md` 含 core 指针;`_ds_sync.json` `bundleSha12` 已刷新。

---

## 后续（非本计划代码任务）

- **L5 并行实测（owner 侧）**：在两项目各跑零提示设计,观察实际遵守哪些规则 → 校准哪层承重,回来后可能微调 L1–L4。
- **附带发现（可选顺手修）**：`CLAUDE_DESIGN_RULES.md` Logo 条引用的 `reference/14-email-templates.md §Header/§Logo` + `preview/brand-logo.html` 在包里不存在（14 实为 upstream-gate、无 preview 目录）→ 收敛为有效出处 `reference/icon-keys-brand.md`。
