# BRIDGE-MOCKUP-008 Closure — SoT 升级 Figma 库全镜像 + batch authoring + sync 机制

> Closure date: 2026-05-28
> Total span: 2026-05-27 (BRIDGE-MOCKUP-007 ROI PASS → BRIDGE-MOCKUP-008 open) → 2026-05-28 (4 phase shipped)
> Final commits: `6afd6a2c` (Phase B-v2) → `652bed79` (Phase C) → `71aff271` (Phase D) → `e173d4bc` (doc-lag follow-up)

---

## 一句话总结

`docs/internal/affordance-categories.json` SoT 从 **35-icon pilot** 升级为 **Figma 库全镜像 643 entries**，并配套 **figma-vs-sot drift audit** wire 进 sync pipeline Step 14，杜绝未来 designer 加/删/重命名 icon 导致 SoT 静默漂移。

---

## 战略前提（why this sprint）

BRIDGE-MOCKUP-007 三轮 ROI gate 实验（2026-05-27）：

| 轮次 | 假设 | Δ accuracy | 结论 |
|---|---|---|---|
| v1 code-AI text | SoT 加 affordance 给 code AI 选 icon | 0pp (8/8 vs 8/8 ceiling) | 测试集天花板太高，无法 measure |
| v2 name-naive 升级 | name 不带语义时 SoT 救场 | 0pp (manifest+registry 已 4 层冗余编码 affordance) | 现有冗余足够 |
| **v3 mockup-AI Figma** | mockup AI 真画 Figma 时 SoT 增益 | **+44pp PASS** (A=4.5/8 / B=8/8) | 3 个 value case 实证：T3 rescue (search 不到 sun/moon → SoT picture-light 救场) / T2/T4/T6 variant precision / T1/T7 user-confirmed A 找到的 mark/favorite + Message/Help **比 SoT registered 更好** |

**关键 finding**：T1/T7 user-pick 比 pilot 35 entries 好 → 暴露 **scope hole**。

**战略 pivot**：
- SoT 目标：~~icon 语义数据库~~ → **mockup 一致性收敛器**
- Scope：manifest(642) → **Figma 库全镜像 ~650+ published icon components**
- 方法：demand-driven trickle → **batch 集中处理**（一次 author 完所有 icon，未来 incremental 只补 figma 新增）

---

## 4 Phase shipped

### Phase A — worklist extract (~0.5-1h)

`scripts/extract-figma-icon-worklist.mjs` — 从 `figma-data/normalized/components.manifest.json` 拉所有 `figmaName.startsWith("icon/")` published entries，标识 35 已有 SoT entries → 输出 `docs/internal/bridge-mockup-008-icon-worklist.{json,md}`（605 todo + 35 done）。INFRA-F35 Phase 4 sync pipeline Step 13 wire（非阻塞 audit）。

### Phase B-v2 — Codex batch author (commit `6afd6a2c`, ~10-15h)

Multi-batch range introduce + promote 608 drafts。**关键 finding**：

1. **命名 spec 升级 15 → 18-enum**：input/output 从 network/* 拆出独立 category；最终 18 个 `affordance_category` enum 在 `icon-naming-convention.md`
2. **R1-R5 核心原则 codified**（`icon-naming-convention.md` §0）：
   - R1: cat 跟 Figma folder（不跨 cat 移动 entries）
   - R2: 同 leaf 不同 cat OK（`input/facebook` + `output/facebook` 共存）
   - R3: cat==folder 时 leaf 不重复（`indicator/x` 而非 `indicator/indicator-x`）
   - R4: kebab 连接
   - R5: 数字 suffix 按图形特点（如 `chevron-left`, `chevron-right` 对应 Figma `Arrow/left_2`, `Arrow/right_2`）
3. **5 plan owner cross-category overrides accumulated** — Codex batch author 后 plan owner 跨 category 手动校准
4. **Codex JSON-string SVG vs template literal 格式差异**（P2 cosmetic finding，audit 已兼容）

### Phase C — merge to SoT (commit `652bed79`, ~5-8h user review)

608 drafts user batch-review accept → merge 进 `affordance-categories.json` SoT（35 → **643 entries**）+ 11 new category files；icon manifest aggregate 643 ✅。

### Phase D — figma-vs-sot drift audit (commit `71aff271`, ~2h Codex + ~30min plan owner)

**Spec**: `figma-sync/audit-figma-vs-sot.mjs` (316 行) 按 `figma_component_key` 对比 Figma manifest vs SoT，5 类 drift：
- **A** figma-only（figma 有 SoT 缺）— strict blocking
- **B** sot-orphan（SoT 有 figma 缺）— strict blocking
- **C** figma_name drift（rename）— strict blocking
- **D** node-id drift — warning
- **E** svg-content drift — placeholder (v2 implementation)

Wire 进 `sync:figma-library` Step 14 + `--skip-sot-audit` opt-out + `pnpm audit:figma-vs-sot` script。

**首次实跑**: figma=643 vs sot=643, A=0/B=0/**C=3**/D=0：
| component_key | SoT was | Figma 真源 | 类别 |
|---|---|---|---|
| `655b…` | `icon/Arrow/left` | `icon/Arrow/left_2` | R5 数字 suffix（pair `Left_1` 已存在） |
| `2d87…` | `icon/Arrow/right` | `icon/Arrow/right_2` | 同上 |
| `b7d7…` | `icon/Time/Calender` | `icon/Time/Calendar` | **Figma 端 typo fix** |

Plan owner independent verify（component_key + nodeId 全对，仅 `figma_name` 字段漂移）→ in-place patch SoT → 复跑 A=B=C=D=0 ✅。

### Doc-lag follow-up (commit `e173d4bc`)

Sprint Self-Audit 7-类 (INFRA-F37 Phase 5 expanded A/B/C → A-G mandatory) 跑后 C-class doc-lag findings 一并 closure：

- `divergences.md §time/calendar` — divergence ✅ resolved（Figma 端 typo 已落地）
- `affordance-categories.json` 3 entry 的 `path` 字段（`Time/Calender.svg`、`Arrow/left.svg`、`Arrow/right.svg`） + Calendar `notes` 字段（删除 "designer typo preserved" misinformation）
- `AGENTS.md §"同步 Figma 库"` 11-step → **14-step**（F35 +12/13 + Phase D +14）
- `tracker.md` 增 Phase D 已完成 entry

---

## 战略学习（generalize beyond this sprint）

### 1. ROI gate 实验法（"v3 mockup-AI"）值得 codify

`docs/internal/retrospection/2026-05-27-bridge-mockup-007-roi-validation.md` 完整记录的 3-轮 gate (v1 code-AI text / v2 name-naive / v3 mockup-AI 真画 Figma) 是新工作量验证范式：**不直接做 N×scope expansion，先做半小时 5-10 case 对照实验**，Δ≥某 threshold 才扩量。[[project_bridge-mockup-007-roi-gate]] memory 已记录。

### 2. "Figma 真源 + 持续 drift 检测"模式

Phase D 让 SoT 一次 author 完后**不再依赖人工对照 Figma**。任何 designer 改名 / 加 / 删 → sync pipeline Step 14 自动报警。这是 [[trigger-O-product-truth-over-onboarding]] 元规则的具体落地：**onboarding 知识有 staleness 风险，需要 audit 持续验证产品真值**。

### 3. memory 实证完成 → divergence closure

`[[feedback_name-search-absent-fallacy]]` 2026-05-26 case（grep `Calendar` 全 miss 因为 Figma 是 `Calender` typo）→ user 当时建议 Figma 端正名 → 今天 Phase D drift 报警证实**已落地**。memory 实证完成 = divergence closure 触发器；不应永远保留 "modification direction: figma 端重命名" 这种 open-ended action。

### 4. Codex / 别 session merge 协同

Phase D Codex 编辑的 `package.json` / `AGENTS.md` / `backlog.md` 被**别 session INFRA-F37 Phase 2 commit `78be263a`** 一并 staged。说明 **并行 session + 共享 worktree** 模式下，commit 边界不总是按 sprint 干净切分；audit:figma-vs-sot 这个 script 注册到 package.json 实际是 INFRA-F37 commit 落的，不是 Phase D commit。这非 bug，但下次写 retrospect 引 commit hash 时需要核对实际 staged 范围。

### 5. Sprint Self-Audit 7-类落地实证

INFRA-F37 Phase 2 同 session 把 Self-Audit 从 3 类 (A/B/C) 扩到 7 类 (D canonical-compliance / E hard-rule / F render-verification-coverage / G figma-library-vs-canonical)。Phase D commit 后实跑 7 类全 audit — D/F/G 暴露的全是 pre-existing CANONICAL-012-016 entries（已 backlog），证明协议工作：**新 sprint 不引入新 drift，但持续 surface pre-existing tech debt**。

---

## 数字 baseline (post-closure)

| 项 | 值 |
|---|---|
| SoT entries (affordance-categories.json) | 35 → **643** |
| Figma published icon components | 643 |
| icon-naming `affordance_category` enum | **18**（input/output 独立） |
| sync pipeline steps | 11 → **14**（F35 +12/13 + Phase D +14） |
| Self-Audit 类别 | 3 → **7**（D/E/F/G via INFRA-F37 Phase 2） |
| audit:figma-vs-sot 当前 drift | A=0 B=0 C=0 D=0 ✅ |

---

## Follow-up (未在本 sprint 处理)

| # | 项 | 估时 | 优先级 |
|---|---|---|---|
| FU-1 | `audit-figma-vs-sot.mjs` v2: + `path` drift detection (treat SoT `path` field as 4th drift surface) | ~30min | P2 |
| FU-2 | `audit-figma-vs-sot.mjs` v2: + duplicate `figma_component_key` guard (defense-in-depth) | ~10min | P2 |
| FU-3 | drift type E (svg-content-drift) v2 implementation — currently placeholder | ~1-2h | P2，看 svg content drift 实际频率 |
| FU-4 | Pre-commit hook promote D/E/F/G audit（INFRA-F37 Phase 6 defer） | ~1h | P1，等 D/F/G baseline cleared |

---

## 关联文件 / commits

- 战略凭据: [`2026-05-27-bridge-mockup-007-roi-validation.md`](./2026-05-27-bridge-mockup-007-roi-validation.md)
- 命名 spec: [`docs/internal/icon-naming-convention.md`](../icon-naming-convention.md) §0 R1-R5
- 排期 SoT: [`design-spec-canonical-alignment-tracker.md`](./design-spec-canonical-alignment-tracker.md) 新增 BRIDGE-MOCKUP-008 Phase D entry
- backlog closure: `docs/internal/backlog.md` BRIDGE-MOCKUP-008 entry ✅ shipped 标识 (in 78be263a)
- audit script: `figma-sync/audit-figma-vs-sot.mjs`
- prompt: `docs/internal/_prompts/archived/bridge-mockup-008-phase-d-sync-mechanism.prompt.md`
- commits: `6afd6a2c` / `652bed79` / `78be263a` (含 audit:figma-vs-sot script reg) / `71aff271` / `e173d4bc`

---

## 闭环 trigger

- ✅ Backlog `BRIDGE-MOCKUP-008` entry 标 shipped (in commit `78be263a`)
- ✅ STATUS.md Phase D narrative 更新 (commit `71aff271`)
- ✅ Tracker §轨道 A 已完成 entry 新增 Phase D row (commit `e173d4bc`)
- ✅ Self-Audit 7 类全跑 — D/E/F/G pre-existing finding 都已 backlog (CANONICAL-012-016)
- ✅ memory [[feedback_name-search-absent-fallacy]] 实证完成 (Calendar typo divergence closure)

BRIDGE-MOCKUP-008 **closed**. Next sprint route 见 STATUS.md narrative top (INFRA-F37 D/F/G baseline cleanup or v0.7 contrast cleanup main line)。
