# T4-Spike Validated + Badge 双源处置 复盘（2026-04-30）

## TL;DR

- **起点**：T1c Round 1 plan 写完，用户元层面 break："感觉越来越复杂，确定是往项目目标上靠拢吗？"
- **转折**：T1c PAUSED，pivot T4-spike on Badge vertical slice 验证项目目标
- **核心结果**：**项目目标"AI 拿 Figma URL → 1:1 还原"端到端验证 PASS**（Claude + Codex 双 AI 工具，同 URL 输出一致；7 行属性级对照全 ✅）
- **副产物**：发现 Badge canonical/legacy 双源 + 处置；16 wrapper 组件 healthy 架构清单登记
- **Milestone commit**：b9e5ac3

---

## 阶段 1：T1c Round 1 plan 设计 + 元层面 break

### 推进
- 写 T1c Round 1 plan-only prompt：figma-sync extract pipeline 递归子节点 schema 升级
- 根因诊断：8 组件 / 171 figma-data-missing 来自 `extract.mjs:134-162` 只抽顶层 paint，子节点全丢
- Round 1 executor 产出：[t1c-extract-recurse-plan.md](../_plans/t1c-extract-recurse-plan.md) (382 行) + [figma-extract-rules.draft.md](../../src/design-system/translation/figma-extract-rules.draft.md) (107 行)
- 复审 PASS：反模式 #1/#2/#3/#4/#5 全 ✅；executor 用 `node -e` 实读 JSON 真源（触发器 I 健康运转），数据准过我之前 awk

### 用户 break 信号（触发器 A）

> "我不知道这个跟你这个有什么关联？感觉越来越复杂，确定是往项目目标上靠拢吗？感觉还差很多"

### plan owner 反思

我陷入"逐层修底层"：T1a fix v2 三轮 → T1b → T1c R1 累计是 audit infrastructure，未碰过项目目标"AI 拿 URL → 1:1"。21 组件中 13 个本来就干净（无 figma-data-missing），不依赖 T1c 也可上 T4。**真问题是优先级判断错**——稳妥但远离项目目标可见价值。

决策：T1c PAUSED，pivot T4-spike Badge。

---

## 阶段 2：T4-spike Badge 设计

### 选 Badge 不选 Button 的过程

我第一推荐 Button（看 audit 段 token-match-via-indirection 数字大就以为简单），用户问"那么推荐我做什么？"。我开始写 prompt 时实读 raw JSON 才发现 Button 在 Figma 是 **9 个 component set**（dark/light × XS/S/M/L + url-link），3200+ variants，spike 不合适。改 Badge：1 COMPONENT_SET × 3 axes × 30 variants。

### Round 1 产出

| 文件 | 用途 |
|---|---|
| `src/components/Badge/Badge.figma.ts` | Code Connect 模板 |
| `figma-data/normalized/ai-manifest.spike.json` | schema v0.1-spike |
| `docs/internal/_spikes/badge-vertical-slice-test.md` | 3 测试方案 |
| `package.json` + `pnpm-lock.yaml` | `@figma/code-connect` 装为 devDep |

### 我 prompt 模板的两个 bug（executor 纠正）

- **文件路径写错**：prompt 反复写 `src/components/Badge/Badge.vue`，真源是 `src/canonical/Badge.vue`
- **prop 值大小写写错**：prompt 示例用 lowercase（`Black: 'black'`），真源是 PascalCase（`Black: 'Black'`）

Codex 读代码事实自行纠正——按触发器 G "schema 设计 vs 实例填充"分工：plan owner 框定 schema，executor 读代码事实扩展实例。executor 比 plan owner 凭印象准。

---

## 阶段 3：3 测试实跑 + 揭露架构问题

### 测试矩阵

| 测试 | AI | 输入 | 输出 | 1:1 |
|---|---|---|---|---|
| 1 | Codex | URL + .figma.ts + canonical/Badge.vue | `<Badge color="Red" tag="Filled" type="Circle">5</Badge>` | ✅ PASS |
| 3 | Claude（无指令）| 只贴 URL | 问回意图（合理谨慎，不算 fail） | — |
| 1+3 | Claude（加指令，**LEGACY 注释前**） | URL + 指令 | `<Badge :count="5" type="red" size="m" />` | ❌ FAIL — 落 legacy |
| 1+3 | Claude（加指令，**LEGACY 注释后**） | URL + 指令 | `<Badge color="Red" tag="Filled" type="Circle">5</Badge>` | ✅ PASS |

### 关键发现：仓库有架构歧义

Claude 和 Codex 对同一 URL 输出不一致，根因是落到不同 Badge.vue：

- Codex 顺 `src/index.ts:8` 追到 `src/canonical/Badge.vue`
- Claude 按路径启发式（"components 在 src/components/X/X.vue"）落 `src/components/Badge/Badge.vue`（legacy）

两者推理都对——**输入不同所以输出不同**。仓库本身让 AI 工具落点不一致。

### 我误判一次："18 组件双源"

第一次 audit 用 `grep -c "Base$c\|from.*components/$c"` case-sensitive，错过 `import Checkbox from '../components/Checkbox/Checkbox.vue'`（文件名 lowercase b）。结论"18 组件双源"。

重 audit case-insensitive：**真双源只 1 个（Badge）**。其它 17 个都是 wrapper 模式（canonical 内 `import Base<X> from '../components/<X>/<X>.vue'`），是健康架构。

教训：grep 命令缺陷误判（触发器 I）——但我这次没第一时间用 `node -e` / 文件实读核对，直到读 CheckBox 文件才发现 case-mismatch。下次类似多组件 audit 必须先抽样实读 1-2 个文件验证 grep 逻辑。

---

## 阶段 4：30min 最小动作处置

### 改动（plan owner 角色 + 用户授权）

- [`divergences.md`](../../src/design-system/translation/divergences.md) 加 "Code 端双源（AI 工具消费指引）" 段，登记 Badge SoT = canonical / legacy 仅 playground 等场景使用
- [`Badge.vue`](../../src/components/Badge/Badge.vue)（legacy）文件头加 ⚠️ LEGACY 警告注释，引 AI 走 canonical
- 16 wrapper 组件**不动**（健康架构清单登记在 divergences.md）

### Claude 重跑 PASS + 反馈

> "正确指引被测 AI 走 SoT 的关键是 Badge.vue 顶部的 LEGACY 警告注释——它告示式说 'AI tools generating Vue code from a Figma URL: use src/canonical/Badge.vue as the source of truth'。"

LEGACY 警告注释 = AI-readable 引导机制，比 .figma.ts / manifest 更轻量更直接。

---

## 阶段 5：用户 redirect Code Connect 立场

### 我之前偏见

看完 Claude 反馈"测试 3 也能 pass" → 推断 .figma.ts / manifest 在简单组件上可能多余。这是 spike 视角偏狭——**只看"AI 生成代码"维度**。

### 用户正确角度

> "我还是比较建议 code Connect 的，因为这样一旦 Figma 组件有更新，执行 Figma 组件同步就很快能找到，无需大量搜索、差异对比等工作"

### 立场修正

`.figma.ts` 双价值：

| 维度 | 不要 .figma.ts | 要 .figma.ts |
|---|---|---|
| AI 拿 URL → 生成代码 | ✅ 简单组件可行 | ✅ 显式映射更稳 |
| **Figma 改组件 → 找影响代码** | ❌ 全库 grep + 差异对比 | ✅ `figma connect` 精确报告 |
| 长期可维护性 | ❌ 漂移风险 | ✅ 硬绑定 |

`.figma.ts` 是 T4 必产物，21 组件全部要写。AI 生成 = bonus，**Figma 同步 = 主价值**。

---

## 关键决策汇总

| 决策 | 落地位置 |
|---|---|
| T1c PAUSED（不删 Round 1 产物，保留 resume context） | commit b9e5ac3 |
| T4-spike Badge 完整端到端验证 | commit b9e5ac3 |
| Badge canonical = SoT, legacy 加 LEGACY 警告 | divergences.md + Badge.vue 注释 |
| 16 wrapper 组件 = healthy 架构，不动 | divergences.md "Code 端双源" 段 |
| `.figma.ts` 是 T4 必产物，不是简单组件可选项 | spike test md "实测反馈" 段 |

---

## 反思（meta-rules 实证）

### ✅ 触发器 A 命中 + 正确响应

用户元层面"越来越复杂"→ 立即 stop T1c，回应元层面问题，pivot 给项目目标可见价值。没辩解、没空承诺、给机制化对策（spike 验证）。

### ✅ 触发器 G 健康运转

我 prompt 写错文件路径 + 大小写 → executor (Codex) 读代码事实纠正。不是我手填全部实例，而是 schema 我框定 + executor 按代码事实扩展。**executor 读代码事实比 plan owner 凭印象准**。

### ⚠️ 我犯的反模式

| 反模式 | 实例 | 修正 |
|---|---|---|
| 推荐基于"audit 数字大 = 简单"启发式 | 推 Button spike → 实际 9 sets 3200+ variants 不合适 | 改 Badge 前先实读 raw JSON |
| grep case-sensitive 误判多组件状态 | "18 组件双源" → 实际 1 个 | 多组件 audit 先抽样实读验证 grep 逻辑 |
| spike 视角偏狭看价值 | 推断 .figma.ts 可能多余 | 用户提醒 Figma 同步主价值才修正 |

---

## 阶段 6：通用机制验证（rule #6） + Pro plan 限制发现

### 推进

用户问得好："你只在 Badge 一个组件加 LEGACY 警告，其他 17 wrapper 组件是不是也有这个问题？是不是有通用方式？"

### 验证盲点

抽样 3 个 wrapper 组件 (Tooltip / Slider / Breadcrumb) 比对 canonical vs base API：

| 组件 | canonical API | base API | 错位 |
|---|---|---|---|
| Tooltip | `darkTheme: DarkTheme` | `content: string` | ❌ |
| Slider | `size: Size` | `modelValue: number` | ❌ |
| Breadcrumb | (待查) | (待查) | 推测 ❌ |

→ 17 wrapper 组件**潜在**也有 AI 工具落错风险，比 Badge 弱（base 仍被 canonical 真实 import，不孤立）。

### 通用机制：AGENTS.md 加硬规则 #6

不打补丁式给 17 个 base 加 header（违反反模式 #2），而是**改 1 处真源 + AI 工具协议读必读链路**：

```
| 6 | AI 工具从 Figma URL 生成代码必须用 src/canonical/* 作为 SoT，不用 src/components/* | base/legacy 是实现层，canonical 是 Figma-aligned 桥层 |
```

三层防护：
1. L1: AGENTS.md 必读链路 + 硬规则 #6（覆盖 18 + 未来新增）
2. L2: divergences.md "Code 端双源" 段（明示 16 wrapper 不动）
3. L3: Badge legacy 文件头警告（孤立特例兜底）

### Tooltip 验证 — 通用机制 PASS

新 Claude session 跑同样测试（Figma URL `node-id=1408-17135`）：

- ✅ Claude 第一步读 AGENTS.md + 复盘文档
- ✅ **显式引用 "Per 项目硬规则 #6"** by number
- ✅ 落 src/canonical/Tooltip.vue（不是 src/components/Tooltip/Tooltip.vue）
- ✅ 输出 `<Tooltip dark-theme="on" pointing="left down" content="Description">...</Tooltip>` (Figma-aligned API)
- ✅ 自验清单引用 #2/#3/#4/#5/#6 五条硬规则做合规检查

**结论**：rule #6 通用机制有效——AI 工具协议读必读链路是充分的，不需要给 17 wrapper base 加 header。

### 副作用：Pro plan 阻断 Code Connect publish

Tooltip 测试中 `get_code_connect_map` 返回：

> "You need a Developer seat in an Organization or Enterprise plan to access Code Connect."

意味着 `figma connect publish` 需要 Org/Ent 席位，Pro plan 不可达。

之前 [t4-spike-figma-connect-publish.prompt.md](../_prompts/t4-spike-figma-connect-publish.prompt.md) 假设 Pro 够用是错的——没在 fire 之前 catch 这个 pre-flight 失败。

### 决策：T4 batch DEFERRED

| 价值 | Pro tier | 当前 |
|---|---|---|
| AI 拿 URL → 1:1 还原 | ✅ rule #6 + canonical + divergences | ✅ 已落地 |
| 多 AI 收敛到 canonical | ✅ 同上 | ✅ |
| Figma 改 → 找代码 | ✅ `pnpm sync:figma-library` audit | ✅ 已有 |
| Code Connect publish + DevMode 显代码片段 | ❌ 需 Org/Ent | — |

写 20 个 .figma.ts 在 Pro plan 上**主要是 Org 升级投机价值**，不是当前 ROI。决策：

- **T4 batch DEFERRED** until Org plan upgrade
- **跳到 T2 / T3** —— docs site + EP 风格分类，开发者拿到的实际价值

---

## 待办（更新于 commit aaa537f T3 milestone 之后）

- ~~T4 batch（20 组件 .figma.ts）~~ → **DEFERRED until Org upgrade**
- ~~T3 EP 分类（22 页导航重组）~~ → **✅ done in commit aaa537f**（与 Round B 一并落地：8 EP group + 28 page figma 元数据 + @/ alias 统一）
- **T2 样板**：3 个组件 docs 页改造——**修正后样板：Badge / Tooltip / Select**（原 v2 plan 的 Progress / Notification 在 figma-data-missing 8 组件清单里，依赖 T1c PAUSED；改用 Badge/Tooltip/Select，已 spike 验证 + figma-data 干净，避开 T1c 阻塞）
- **T1c**：暂保留 PAUSED 状态。13 干净组件已通过 rule #6 桥接，不依赖 T1c；8 阻塞组件如有 T2 推进需求时再补
- **figma connect publish 链路**：等 Org plan 升级时再做（之前 [Path B prompt](../_prompts/t4-spike-figma-connect-publish.prompt.md) 加 DEFERRED 头）

### 隐性风险扫描发现的延后任务（2026-04-30 plan owner 扫描产出）

T3 Round B 已顺手清理 3 项（`.gitignore` 加 raw-cache / 删 `.claude/component-plan.md` / 跑 `pnpm build` 刷新 dist）。剩余 4 项延后单独追踪：

- ~~**tsconfig include 扩 playground/**（HIGH 优先级）~~ → **✅ DONE**（Round 1 dry-run 暴露 21 type 错误，Round 2 修完，typecheck 0 错误。永久扩 include + 加 `playground/types/raw.d.ts` ambient + 修 8 文件 + cascade readonly 到 base Table。详见 [dryrun-report](../_spikes/tsconfig-include-extension-dryrun-report.md) 和 Round 2 修复 commit）
- **figma-data 定期 sync**（持续行为）：现有 figma-data/raw/ 为 Apr 28，Figma 端是否更新未知。按需主动跑 `pnpm sync:figma-library`（AGENTS.md 安全模式），不强制频率
- **figma.config.json init**（DEFERRED to Org upgrade）：@figma/code-connect 装了未 init。Org 升级时跟 T4 batch 一起做
- **`inject<any>` 类型化**（LOW，可选）：`src/components/Tab/TabItem.vue` + `src/components/Steps/StepItem.vue` 6 处 Vue provide/inject 用 any。低价值 refactor，看 review 时是否一并做

---

## 工作区状态

- HEAD: 待 commit（本次 follow-up milestone）
- AGENTS.md 加硬规则 #6
- Spike test md + 本复盘加阶段 6 内容
- v2 plan 标 T4-spike COMPLETE (Pro tier) + T4 batch DEFERRED
