# Prompt — T2 样板 Badge Round 2（implementation + audit run）

> **角色**：executor
> **范围**：按 [`docs/internal/_plans/t2-sample-badge-plan.md`](../../_plans/t2-sample-badge-plan.md)（plan owner 定稿） + 三份 Round 1 draft（plan owner 裁定后版本，下方 §0 列出全部裁定）实现 generator + grid 组件 + BadgePage 改造 + 4 audit 合并跑 + 视觉验收。
>
> ⚠️ **不要 commit / 不要 git add**——所有改动 dirty 工作区累积，等 plan owner 复审完 Round 2 产出才进 M1 里程碑 commit。
> ⚠️ 完成后 **STOP**，按底部"完成报告"格式回报。
> ⚠️ 本轮**不扩范围到 Tooltip / Select**——只 Badge。
> ⚠️ 实现中如发现 plan / 裁定与代码事实冲突的 **blocker**（不只是命名/风格分歧），先指出再决定是否执行；不扩展替代路线。

---

## §0 — 17 条 plan owner 裁定（最终决议，executor 直接按此实现，不再询问）

### Generator schema 裁定（draft 1 修正）

| # | 项 | 裁定 |
|---|---|---|
| D1 | 输出文件名 | `badge.ts` |
| D2 | `axes` shape | `Array<{ figmaAxis: string; codeProp: string; values: readonly string[]; valueCase: 'figma-original' }>` |
| D3 | `variants` shape | `Array<{ variantId: string; figmaName: string; props: TProps; theme?: 'dark' \| 'light' }>` |
| D4 | source 字段 | 保留 `figmaFileKey` / `figmaNodeId` / `figmaPage` / `figmaPageId` / `sourceFile` |
| D5 | prop value case | 保 Figma 原值（PascalCase） |
| D6 | S5 theme 表达 | `variant.theme?: 'dark' \| 'light'`；Badge 全部 variant 不含此字段 |

### Generator schema **必须删除**（draft 1 加料字段）

- ❌ `source.rawSourceFile`
- ❌ `source.rawSha256`
- ❌ `source.sourceLayer`
- ❌ `meta.evidenceLevel`
- ❌ `meta.evidenceSource`
- ❌ `meta.generatorVersion`（与根 `schemaVersion` 重复，**保根级 `schemaVersion: 't2-sample-v0.1'`**）

### Grid 组件裁定（draft 2 修正）

| # | 项 | 裁定 |
|---|---|---|
| D7 | site theme 注入方式 | `siteTheme?: 'dark' \| 'light'` prop（默认 `'dark'`，与 docs site 当前 dark-only 一致） |
| D8 | 待渲染组件注入 | `component: Component` prop + `<component :is>`；**禁止默认 slot**（cell 只渲染 `<component :is v-bind="variant.props" />`） |
| D9 | data-* attr 命名 | section 边界 `data-figma-members`；cell `<article>` + 内 `<component>` 都带 `data-figma-source="generator"` + `:data-figma-member="variant.variantId"` + `:data-figma-component="members.component"` |
| D10 | meta 行字符串 | grid 内置默认 `source=<Component> · nodeId=<id> · variant count=<visibleCount>`；可选 `metaLabel?: (members, visibleCount) => string` 回调（page 不能传死值，必须回调签名） |

### Grid 实现额外约束

- **不允许** grid SFC 内出现 `<slot>` 节点（与 D8 联动）
- **不允许** grid 内置 Try It / 手写 demo / 静态字符串展示
- CSS 仅用 docs-site 现有 token：`var(--bg-layer*)` / `var(--line-divider-light)` / `var(--text-*)` / `var(--brand)` 等；**禁 hex/rgb literal**（δ audit 入口）

### Audit 裁定（draft 3 修正）

| # | 项 | 裁定 |
|---|---|---|
| D11 | 静态扫 vs 编译产物 | 静态扫（用 `@vue/compiler-sfc` AST 解析；不跑 dev server / 不读编译产物） |
| D12 | grid 区块定位 | section `data-figma-members` 在 **grid SFC 根内**（不在 page 内手写 wrapper） |
| D13 | CSS 变量定义 hex 豁免 | **不豁免**——3 个文件（`src/canonical/Badge.vue` / `playground/docs/pages/BadgePage.vue` / `playground/docs/components/FigmaMembersGrid.vue`）任一 `<style>` 块出现 hex/rgb literal → fail |
| D14 | 4 audit 单独跑 vs 合并跑 | **合并**：单个 `figma-sync/audit-page-t2-sample.mjs`，内含 4 个函数对应 α/β/γ/δ |
| D15 | 报告路径 | `docs/internal/t2-sample-audit-report.md` |
| D16 | β dynamic prop 处理 | warn（不 fail）；但 Badge 改造后**不应**触发 dynamic unresolved（如触发 = 改造未完成） |
| D17 | meta 行 variant count | visible count（按 site theme 过滤后的可见数；Badge 无 theme 即全数 = 20） |

### Audit **必须删除**（draft 3 修正）

- ❌ γ 边界 case "Grid uses scoped slot" 整段（slot 已禁，无此 case）

### β audit **范围明示**

- **β 覆盖整个 BadgePage 的所有 `<Badge>` 出现**——包含 grid 内（来自 generator）+ Try It 区块 + 手写 Tag/Type/Color 三段对照
- `v-bind="variant.props"` 在 grid 内 `<component :is>` 视为 generator-covered，不展开 audit
- 其它所有静态/可静态解析的 `:prop="..."` 必须值 ∈ generator axes 枚举

---

## §1 — 必读输入

按顺序读：

1. [`AGENTS.md`](../../../AGENTS.md) — 跨工具入口 + 硬规则（特别 #4 token / #6 canonical SoT）
2. [`docs/meta-rules.md`](../../meta-rules.md) — 元规则 + 反模式 + 触发器 G 边界
3. [`docs/internal/_plans/t2-sample-badge-plan.md`](../_plans/t2-sample-badge-plan.md) — plan owner 定稿
4. [`docs/internal/_plans/t2-sample-generator-output-schema.draft.md`](../_plans/t2-sample-generator-output-schema.draft.md) — Round 1 draft（**按本 prompt §0 裁定后用**）
5. [`docs/internal/_plans/t2-sample-grid-contract.draft.md`](../_plans/t2-sample-grid-contract.draft.md) — 同上
6. [`docs/internal/_plans/t2-sample-audit-impl.draft.md`](../_plans/t2-sample-audit-impl.draft.md) — 同上
7. [`figma-data/normalized/components-tokenized/badge__4821_1665.json`](../../../figma-data/normalized/components-tokenized/badge__4821_1665.json) — Badge figma 真源
8. [`src/canonical/Badge.vue`](../../../src/canonical/Badge.vue) — Badge canonical
9. [`playground/docs/pages/BadgePage.vue`](../../../playground/docs/pages/BadgePage.vue) — 待改造 page
10. [`playground/docs/components/DocsExampleBlock.vue`](../../../playground/docs/components/DocsExampleBlock.vue) — 同 folder 既有组件，参考样式 token / 类名风格

依赖检查：
- 项目是否已装 `@vue/compiler-sfc`？查 `package.json`——Vue 项目通常已含。如未装，**先报告再行动**（不擅自 install）

---

## §2 — 任务清单

### 任务 2.1 — 写 generator schema 类型文件 + Badge 输出

产出 2 个文件：

**(a) `figma-data/normalized/docs-figma-members/types.ts`** — 共享类型定义

按 §0 D1-D6 裁定，包含：

```ts
export interface DocsFigmaSource { /* figmaFileKey/figmaNodeId/figmaPage/figmaPageId/sourceFile */ }
export interface DocsFigmaAxis { /* figmaAxis/codeProp/values/valueCase */ }
export interface DocsFigmaVariant<TProps extends Record<string, string> = Record<string, string>> {
  variantId: string
  figmaName: string
  props: TProps
  theme?: 'dark' | 'light'
}
export interface DocsFigmaMembers<TProps extends Record<string, string> = Record<string, string>> {
  schemaVersion: 't2-sample-v0.1'
  component: string
  source: DocsFigmaSource
  axes: readonly DocsFigmaAxis[]
  variants: readonly DocsFigmaVariant<TProps>[]
  meta: {
    generatedAt: string
    sourceFile: string
    variantCount: number
  }
}
```

**(b) `figma-data/normalized/docs-figma-members/badge.ts`** — Badge generator 输出

由任务 2.2 的 generator 脚本生成，**不要手写**——本任务只是约定文件位置 + 类型形态。

### 任务 2.2 — 写 generator 脚本

产出 `figma-sync/generate-docs-figma-members.mjs`：

- 读 `figma-data/normalized/components-tokenized/badge__4821_1665.json`
- 解析 variant `name` 字段（如 `'Type=Circle, Color=Green, Tag=Filled'`）拆 prop tuple——参考 Round 1 draft 1 的 Badge 实例输出
- 收集 axes + values（保 figma 原序：先出现 = 先序）
- 生成 `figma-data/normalized/docs-figma-members/badge.ts`，结构严格按 §0 裁定后的 schema
- 头部加 `// generated by figma-sync/generate-docs-figma-members.mjs — DO NOT EDIT`
- 跑：`node figma-sync/generate-docs-figma-members.mjs Badge`（CLI 接组件名参数）
- **本轮只支持 Badge**——其他组件名传入应 fail loud（不 silently fallback）

`package.json` script 提议（不强制添加，先列给 plan owner 审）：

```json
"scripts": {
  "generate:docs-figma-members": "node figma-sync/generate-docs-figma-members.mjs"
}
```

### 任务 2.3 — 写 FigmaMembersGrid.vue

产出 `playground/docs/components/FigmaMembersGrid.vue`：

- Vue SFC，`<script setup lang="ts" generic="TProps extends Record<string, string>">`
- props 按 §0 D7/D8/D10 裁定
- template 按 §0 D9 / D12 / Grid 实现额外约束：
  - 根 `<section data-figma-members :data-figma-component="members.component">`
  - meta 行（默认模板 + 可选 `metaLabel` 回调）
  - axes summary chips（参考既有 BadgePage 的 `coverage-chip` 类名风格保持一致）
  - variant grid：每 variant 一个 `<article class="figma-members-grid__cell" data-figma-source="generator" :data-figma-member="variant.variantId" :data-figma-component="members.component">`
    - 内含 label：`Type=Circle, Color=Green, Tag=Filled` 默认格式
    - 内含 `<component :is="component" v-bind="variant.props" data-figma-source="generator" :data-figma-member="variant.variantId" />`
- **不要** `<slot>`、Try It 控件、静态字符串 demo
- CSS 仅用 docs token；δ 入口要 0 hex/rgb literal

### 任务 2.4 — 改 BadgePage.vue

按下面要求改 [`playground/docs/pages/BadgePage.vue`](../../../playground/docs/pages/BadgePage.vue)：

**改造目标**：

1. **删手写 figma 数据**：
   - 删 `badgeAxes` 数组
   - 删 `badgeColorMembers` 数组（颜色顺序漂移信号）
   - 删 `figmaPage` / `figmaNodeIds` 字面量
   - 删 "variant count=20" 字面量字符串（让 grid meta 自己渲染）
2. **替换 Figma Coverage 段**：
   - 用 `<FigmaMembersGrid :members="badgeFigmaMembers" :component="Badge" :site-theme="'dark'" />` 替代手写 chips
   - import：`import { badgeFigmaMembers } from '@/figma-data/normalized/docs-figma-members/badge'` 和 `import FigmaMembersGrid from '../components/FigmaMembersGrid.vue'`
3. **保留** Tag / Type / Color 三段手写对照 + Try It 区块——它们是 page 的"开发者视角解释"段，不是 figma coverage 段
   - 但所有 `<Badge :prop="...">` 用的值必须 ∈ axes 枚举（β audit 会查；现状用的 Green/Blue/Red/Orange/Black + Circle/Rectangle + Filled/Line 全部合规）
4. **API 表段**：保持现有 `badgeApiRows` 不动（API 表是 plan §1.3 排除项，不是 generator 输出范围）
5. **i18n bilingual handler `t()`** 不动

**关键**：grid 区块和手写对照段、Try It 段、API 表段必须**视觉上能区分**（建议用不同 section title）；γ audit 会查"data-figma-source 标记**只**出现在 grid 内"。

### 任务 2.5 — 写 4 audit 合并脚本

产出 `figma-sync/audit-page-t2-sample.mjs`：

- 入口：`node figma-sync/audit-page-t2-sample.mjs BadgePage`（接 page 名参数）
- 单文件含 4 函数：`auditAlpha()` / `auditBeta()` / `auditGamma()` / `auditDelta()`
- 每函数返回 §0 verdict schema（plan §3.1）的 JS 对象
- 主入口跑 4 个 + 写 `docs/internal/t2-sample-audit-report.md`（markdown 格式参考 draft 3 §通用段）
- 静态扫（D11）：用 `@vue/compiler-sfc` parse SFC + AST 遍历
- δ：CSS 注释剥离保留行号（draft 3 δ 输入读取算法已写清）
- β 范围：BadgePage 全部 `<Badge>` 出现（除 grid 内 `v-bind="variant.props"`）

`package.json` script 提议：

```json
"scripts": {
  "audit:page-t2-sample": "node figma-sync/audit-page-t2-sample.mjs"
}
```

### 任务 2.6 — 跑 generator + audit + 视觉验收

按顺序跑（**不要 commit**）：

```bash
# 1. 生成 Badge generator 输出
node figma-sync/generate-docs-figma-members.mjs Badge

# 2. typecheck（确保 BadgePage import 路径 + types.ts 类型 OK）
pnpm typecheck

# 3. 跑 4 audit
node figma-sync/audit-page-t2-sample.mjs BadgePage

# 4. 看报告
# (executor 自己 cat docs/internal/t2-sample-audit-report.md，验 4 verdict)

# 5. 视觉验收
pnpm dev
# 浏览器开 BadgePage，确认：
#   - Figma Coverage 段渲染了全 20 variants 网格
#   - Try It / Tag/Type/Color 三段对照完好
#   - API 表完好
#   - dark theme 视觉无 regression
# (executor 截图给 plan owner)
```

预期结果：

- α verdict = `N/A`（Badge 无 theme axis）
- β verdict = `pass`
- γ verdict = `pass`
- δ verdict = `pass`

任一 fail → 不要自行"修到 pass"——回报给 plan owner 看 finding 决定怎么改。

---

## §3 — 验收标准（按 plan §5 Round 2）

executor 完成后必须自验：

- [ ] BadgePage.vue 不再含手写 `badgeAxes` / `badgeColorMembers` / `figmaNodeIds` / "variant count=20" 字面量
- [ ] 所有 generator 输出字段严格按 §0 裁定（**没有** rawSourceFile / rawSha256 / sourceLayer / meta.evidenceLevel / meta.evidenceSource / meta.generatorVersion）
- [ ] FigmaMembersGrid.vue **没有** `<slot>` 节点
- [ ] FigmaMembersGrid.vue / BadgePage.vue / canonical/Badge.vue 三个文件 `<style>` 块 **0 hex/rgb literal**（δ audit pass）
- [ ] 4 audit 全部按预期 verdict（α=N/A / β=pass / γ=pass / δ=pass）
- [ ] `pnpm typecheck` 0 错误
- [ ] `pnpm dev` BadgePage 视觉无 regression（截图为证）
- [ ] 没 commit / 没 git add
- [ ] 没扩范围到 Tooltip / Select

---

## §4 — 完成报告（按下方格式回报）

```
## Round 2 完成报告

### 产出文件
- figma-data/normalized/docs-figma-members/types.ts (XXX 行)
- figma-data/normalized/docs-figma-members/badge.ts (XXX 行, generated)
- figma-sync/generate-docs-figma-members.mjs (XXX 行)
- playground/docs/components/FigmaMembersGrid.vue (XXX 行)
- playground/docs/pages/BadgePage.vue (改 +XXX/-XXX 行)
- figma-sync/audit-page-t2-sample.mjs (XXX 行)
- docs/internal/t2-sample-audit-report.md (生成产出)

### Audit 结果
- α theme isolation: <verdict> · evidence=<...>
- β figma axis coverage: <verdict> · evidence=<...>
- γ runtime fabrication: <verdict> · evidence=<...>
- δ token purity: <verdict> · evidence=<...>

### 视觉验收
- pnpm dev 启动: ✓ / 失败原因
- BadgePage 截图路径或描述: ...

### 验收 self-check
- [ ] BadgePage 删了所有手写 figma 字面量
- [ ] generator 输出无加料字段（按 §3 验收清单逐条）
- [ ] grid 无 slot
- [ ] 3 文件 0 hex/rgb literal
- [ ] 4 audit 按预期
- [ ] typecheck 0 错误
- [ ] dev 视觉 OK
- [ ] 没 commit
- [ ] 没扩 Tooltip/Select

### 未解决项 / blocker
[如有，列出；无则写"无"]

STOP — 等 plan owner 复审产出 + 截图后给 milestone commit 指示。
```

---

## §5 — 严守约束总览

- ⚠️ **不要 commit / 不要 git add**——dirty 累积到 M1 一刀
- ⚠️ §0 裁定结果**最终**，不再询问；如发现 blocker（裁定与代码事实冲突）先停下报告，不扩展替代路线
- ⚠️ 不动 Tooltip / Select / 其他 page
- ⚠️ Audit fail 不要自行"修到 pass"——回报 finding
- ⚠️ generator / audit 脚本**不要写新真源 .md**（schema/裁定真源已在 plan + §0；脚本读结果不藏规则——反模式 #1）
- ⚠️ 完成 STOP，按 §4 格式回报
