# 提案：产品级 pattern 索引 —— **✅ 2026-08-14 走 A、MVP 已落地（只做 LCD 一个文件）**

> **⛔ 本文件此后是「当初为什么这么定」的记录，不是待办。** 落地实况的真源 =
> [`ds-health-dimensions.md` §3.5](../../internal/ds-health-dimensions.md)（实测数字 / 判据 / 边界都在那里，⛔ 别在本文件找）。
> 本标题原写「**未立项**」，下方 §状态 原写「⛔ 未获裁定前不开建」—— 两处都已被 owner 2026-08-14 的裁定推翻，
> **保留原文 + 就地标注**，让后来人看得见判据是怎么翻的（⛔ 别删原文改写成「一直是这么定的」）。
>
> ~~**仍未拍的一问 = §7 的 Q2**~~ → **✅ 2026-08-14 owner 同日拍定：走 §7 的候选 (a)** ——
> 挂进 mockup 起手链，落地 = [`AGENTS.md` §Mockup 任务额外必读](../../../AGENTS.md) **第 11 项**
> （跑 `pnpm pattern:lookup <figma URL>`）。⇒ **§7 那条「足以否掉整件事」的最强反对理由已被闭合**：
> 现在有机制保证画之前会看到它。⛔ 但它是**查询不是闸**（L1，always exit 0）——
> 「保证被看到」靠的是它在 mandatory 链里，不是靠拦截。

## 0. 一句话说明（2026-08-14 补 —— owner 反馈「不知道啥意思」）

**「产品级 pattern 索引」= 每个产品自己那份「我这个产品里已经做过哪些模块」的清单。**

举例：Config-T 里已经画过一个「设备状态卡」，下次做新功能又需要一个状态卡时，
如果没人记得它已经存在，就会拿 DS 的 Button / Text 从零再搭一个 —— 两个长得不一样的状态卡。
**owner 描述的原话就是这个场景**：「用了设计库组件、**没用当前产品已有的组件**」。
索引就是让「这个产品里已经有没有干这件事的东西」这个问题**能查**。

⚠️ 注意它和 DS 组件库**不是一回事**：DS 库是跨产品的原子（Button/Input/Table）；
pattern 是**某个产品自己**把这些原子组装成的成品模块（设备状态卡、告警行、参数面板）。
DS 不该收它们（不通用），但产品自己需要记得它们。

~~**⭐ 我的推荐（2026-08-14 上午修订）：先不建，标「已 scoping · 按需触发」。** 理由：owner 看完提案的
第一反应是「不知道啥意思」⇒ 「画之前会有人去查它」这个前提当场不成立，而 §7 写明这是能否定掉整件事的唯一理由。~~

→ **✅ 2026-08-14 owner 读完上面的「设备状态卡」例子后逐字答「我认为很合理」⇒ 上面那条否定理由的
前提被推翻，推荐改回 §5 的 A（机械派生 MVP）。** 留下删除线是为了让后来人看见判据怎么翻的：
**否掉它的从来不是「值不值得」，而是「建了会不会有人查」** —— owner 确认场景成立，这个疑虑就消了。

**⭐ 当前推荐：走 A，但第一步只做一个产品文件**（见文末附录：LCD，file-local 量最大）。
⛔ 仍**别六个一起铺** —— 判据没被真实产物校验过之前铺开，等于把可能错的口径复制六份。
**§7 的 Q2（谁在画之前被强制看到它）不再是开工前置，改为「拿到第一份真产物后再定」** ——
候选 (a) 挂进 mockup 起手链是当前倾向，但那要改已有的必读链，值得先看着实物再拍。

> ~~**状态**：⏳ **提案，等 owner 裁定**。⛔ 未获裁定前**不开建**~~ → **✅ 2026-08-14 owner 裁定走 A，
> 当日落地 MVP（LCD 一个文件）**。本文件仍**不进 backlog**（它不是待办，是决策记录）。
> 原文保留在删除线里 —— 当时的顾虑是「新建设 vs backlog 清零主线」，owner 的裁定即是对该顾虑的答复。
>
> **它是谁的前置**：[`ds-health-dimensions.md`](../../internal/ds-health-dimensions.md) 的
> **DIM-U13「产品内 pattern 复用率」** —— owner 2026-08-13 逐字痛点：「用了设计库组件、
> **没用当前产品已有的组件**」。登记表把这条标成 ❌「需先建 pattern 索引」，理由逐字：
> **「没有索引就没有分母」**。同一件事在 07-08 评估的元层里是 **DIM-X16**（P2，跨产品方案级一致）。

---

## 1. 总计划 / 总数字（AGENTS §AI 响应格式规则 第 1 块）

| 项 | 数 |
|---|---|
| DS 健康度登记表维度总数 | **U 14 · S 8 · Q 11 · E 6 · X 16 = 55 条** |
| 已接上时间序列的 | **6 条**（DIM-U1 三层 / U2 / U3 / U5 / S2 由消费仓扫描器；**DIM-U12 本轮新接**） |
| 判据现成、只差接线的 | 若干（见登记表 `自动=✅` 且基线列空白的行） |
| **本提案要解锁的** | **1 条**（DIM-U13）+ 顺带给 DIM-X16 一个「存在性」以外的答案 |

⛔ 上面这些数**别引用**（契约 G4）：条数从 `docs/internal/ds-health-dimensions.md` 现数，
时间序列从 `docs/internal/_generated/ds-health-history.jsonl` 现读。

## 2. 本次范围

**只出提案，不建索引。** 本轮已做的相邻两件（都已落地、可复核）：
① 组件合规率接上 R2 `aria-expanded` 豁免（判据与闸共用一份）；
② DIM-U12 接上时间序列，并在首测中**发现原口径会误导**（见 §3 的实测证据）。

## 3. 为什么现在提 —— 一条不在计划内的实测证据

跑 DIM-U12 时顺手拿到了**每个产品文件的 file-local 组件实例数**（`remote=false`，按 M36 合法）：

| 产品文件 | file-local 组件实例 | 该文件 INSTANCE 总数 |
|---|---|---|
| LCD（TVU Pack） | 1604 | 10594 |
| Micro-Apps-20250923 | 793 | 13689 |
| Config-T（TVU Pack） | 605 | 30186 |
| MH-2026 | 17 | 15391 |
| Media Service UR | 7 | 12744 |
| PP-2025-2026 | 2 | 16477 |

> ⛔ **这些数是 2026-08-13 实跑值，别引用**（G4）—— 重跑 `node scripts/ds-health-scan-mockups.mjs` 现算。
> ⚠️ 它们是**实例数不是 pattern 数**（一个 pattern 被摆 40 次记 40）。distinct 组件数要另测，见 §5 的 A 方案第 1 步。

**读法**：产品自有 pattern **确实存在且量级悬殊**（1604 vs 2）。悬殊本身就是信息 ——
它意味着「产品已有组件」这件事在不同产品之间根本不是同一个现实，**一个统一的复用率数字会把它们碾平**。

另一条同轮实测的相邻事实：Config-T 的「非指定库实例」里 **19062 个来自它自己 2021 年的老稿**
（`Config T ( Local UI ) V7.7&v8.0 20210909`）。⇒ 「产品已有的组件」有**两种**：
**当前文件里的 file-local**，和**散在历史文件里的**。索引若只收前者，会漏掉后者 —— 而后者
正是「返工」高发地（人找不到，于是重搭）。

## 4. 这个索引到底要回答什么（先定用途，再谈形态）

> 纪律：**先测用途声明，再核数字** —— 数字全对也可能整件事没用。

| 谁 | 什么时候查 | 想得到什么 |
|---|---|---|
| 做新迭代的设计师 / AI | 画之前 | 「这个产品里已经有没有干这件事的东西？」→ 有就复用，没有才从 DS 原语搭 |
| DIM-U13 | 每次测量 | 复用次数 / (复用 + 从 DS 原语重搭) 的**分母** |
| DIM-X16 | 季度 | 跨产品是否在解同一个问题却各搭一套 |

⚠️ **第一行才是它存在的理由**，第二三行是副产品。若索引建成后没人在「画之前」查它，
那它就是又一份会 stale 的派生产物 —— **这是本提案最大的风险，写在 §7**。

## 5. 三条路线（排序 + 默认）

### ⭐ 推荐 · A：从 Figma 产品文件**机械派生**（MVP）

- **怎么建**：每个已登记产品文件（`docs/internal/ds-health-mockup-targets.json` 那 6 个）
  遍历一次，收 `COMPONENT` / `COMPONENT_SET` 节点 → 得到「该产品自有 pattern 清单」
  （名称 · nodeId · 被实例化次数 · 最近修改）。产物 = `docs/internal/_generated/product-pattern-index.json`。
- **成本**：判据现成（与 DIM-U12 同一次文件遍历，**多走一遍同一棵树**）；估 1 个 session 内可跑通。
- **它能答**：「这个产品里有什么」+ 每个 pattern 的热度（实例数）⇒ DIM-U13 的**分母有了**。
- **它答不了**：pattern 的**语义**（这个叫 `Group 61` 的东西是干嘛的）· 该不该复用 · 跨产品同义。
- **G7 合规**：只读团队已有产物，零新增采集，不需要告知任何人。

### B：人工策展的产品 pattern 库（Figma 侧发布）

- 每个产品在 Figma 建一个 published library，把该产品的 pattern 收进去。
- **质量最高**（有语义、有命名、可跨文件引用），但**要设计师持续投入**，且
  ⛔ 撞 AGENTS 硬规则 #1（不修改 Figma）+ §Mockup Write Gate —— 这是**设计师的活，不是 AI 的**。
- **判定**：是终点形态，但**不能当起点**。A 的产物正好是 B 的输入（先看清有什么，再决定收哪些）。

### C：从交付文档 / handoff 反推

- 07-08 元层原文已指出：`REQUEST-INDEX` 是**每产品各一份**、无跨产品索引。
- **判定**：⛔ 不推荐单独走。文档层滞后于 Figma 层，且覆盖不全（未写卡的迭代不在里面）。
  可作 A 的**语义补充**（用交付卡给 pattern 起人话名字）。

## 6. 推荐理由（3 条以内）

1. **A 是唯一「零新增采集、判据现成」的路** —— 与刚落地的 DIM-U12 共用同一次文件遍历，
   不需要任何人改工作方式，也不需要告知任何设计师（G7）。
2. **B 是终点但不能当起点** —— 策展需要先知道「有什么」，而这正是 A 的产物；
   反过来先建库再看，等于让设计师凭印象收，会漏掉 §3 那 1604 个。
3. **A 的产物立刻解锁 DIM-U13 的分母**，而 DIM-U13 是 owner 亲口提的三个痛点之一
   （另两个 DIM-U12 / DIM-U14 —— U12 本轮已接）。

## 7. ⛔ 反对本提案的最强理由（自审：有没有把最省事项包装成 #1）

**有一条，且它足以否掉整件事**：

> 索引建成后，**没有任何机制保证有人在「画之前」查它**。

DS 仓已经有过同形态的教训：派生产物建起来没人消费，就退化成又一份会 stale 的文件，
还要花力气维护。⇒ **owner 若要拍 A，建议同时拍第二问**：

**Q2 · 索引建成后，谁在什么时候被强制看到它？** → **✅ owner 2026-08-14 拍定走 (a)**。候选：
- (a) mockup 起手链（`AGENTS §必读链路 7-10`）加一步「先查本产品 pattern 索引」——
  与既有 Mockup Write Gate 4 步前置同形态，**改的是已有闸的内容，不是新建闸**；
- (b) 只做 report-only，不进链路 —— 那就要接受它可能没人看；
- (c) 先不建，等下一次真的因为「没找到已有组件而重搭」返工时再建（**按需触发**）。

⚠️ 若 owner 选 (c)，本提案应标「已 scoping、按需触发」而不是留在待做 —— 与
[[INFRA-F58]] 残余② 的处置形态一致，避免又一条「标了 P1、一个多月零动作」（那正是
整个健康度机制的缘起）。

## 8. 这一问该谁拍

**owner。** 三条理由：① 它是**新建设**不是修 bug，与「backlog 清零前不新增 entry」直接冲突；
② 路线 B 要动 Figma（硬规则 #1 的边界）；③ §7 的 Q2 决定它会不会变成 stale 产物 ——
那是流程取舍，不是技术选型。

---

## 附 · 若 owner 拍 A，第一步做什么（**别现在做**）

1. 在 `ds-health-scan-mockups.mjs` 的同一次遍历里额外收 `COMPONENT` / `COMPONENT_SET`，
   产出 distinct pattern 清单（先只求「有什么」，不求语义）。
2. ~~先只对**一个**产品文件跑通并给 owner 看真实产物（LCD，因为它 file-local 量最大 = 1604），
   ⛔ 别六个一起铺 —— 判据没被真实数据校验过之前铺开，等于把错口径复制六份。~~
   → **✅ 已执行完，且这条限制已于 2026-08-14 同日拆除**。它落地时被实现成 targets JSON 上的
   `patternIndex: true` opt-in 白名单，而 owner 当场指出那是错的形态：
   **「为什么要把消费级产品一个个拉进来？我要做的是规则，不是实测」**。
   ⇒ 复盘：本条的**理由**（「判据没被校验过之前」）是对的且已被 LCD 那轮满足；错在**实现形态** ——
   把一条「校验完就该失效」的临时限制，做成了一份要人工维护、漏登记就静默少测的常驻清单。
   正确形态应是自宣布失效（`audit-layout-tokens` 的 shrink-only 豁免范式）。⛔ 别再复现这个形态。
3. 拿到产物后**再**回头定 DIM-U13 的分子怎么数（「从 DS 原语重搭」如何机械识别，
   当前**没有**确定性判据 —— 这是 A 之后的下一个真问题，别在 A 里假装已解决）。
