# V4-1646 · LCD WiFi `Other`（隐藏 SSID）设计执行计划

> **上游 gate 产出物** = [`docs/specs/upstream-gate.v4-1646-lcd-wifi-other-hidden-ssid.md`](../specs/upstream-gate.v4-1646-lcd-wifi-other-hidden-ssid.md)（2026-09-09 非追溯）。
> 本文件承接它的 §6「待 owner 确认」，记录本轮已拍板的决策 + 剩余待核项 + 分阶段执行计划。
>
> **档位**：**US-3** / **W3**（三问全中：① 新增手输 SSID 连接能力 ② 新增输入态与 connecting 态 ③ 跨 WiFi 页 + Other 表单页且有前后顺序）⇒ 七件套全产（**⑦ Change Log 已按 D20 免除**，见 §1b-3）。
> 🔴 **2026-09-11 订正**：原文写 US-2（Greenfield 单 frame），与 `mockup-conventions.md:163-164` 的定义不符 —— 本单是在**既有产品文件** `0054ib…`（Touch Screen）里增页增帧，命中 **US-3「Existing product 增/改/删」**。⛔ 别再引用 US-2。
> **报档依据**见 DS `skills/tvu-design-mockup/SKILL.md` §6-JIRA.W。

**目标文件**：Touch Screen v7.7/8.0 `0054ib0nLmt27bC3QlGDl7`（LCD 设备端）
**Jira**：V4-1646（Bug / Medium / Backlog / labels=`[GUI]` / 无 fixVersions / 无 issuelinks）

---

## 1. 本轮已拍板决策（owner 2026-09-09 口头确认）

| # | 决策 | 出处 / 判据 | 关闭了 gate 哪条 |
|---|---|---|---|
| **D1** | **做**，立场按「defer 已被推翻」推进 | owner 本轮说「这个需求你给我设计一下」；Slack winniyang 对客户逐字承诺 `Yes, we will add this function on 8.4.` 晚于 Jira 里的 defer | §6-① |
| **D2** | Security 字段 = **`WPA2` 只读标签**（不是下拉、不是二选一） | owner 本轮选定 | §6-③ |
| **D3** | 只读标签形态 = **白字、右对齐、⛔ 不带下向三角** | 体系内推论：§M17 逐字规定「展开标记 = 下向三角」是唯一可展开信号 ⇒ 无三角 = 不可展开；满足 §C8 一信号一语义。⚠️ **本产品无只读值行先例（两级先例搜索均空）⇒ 真·新值，须立项进视觉契约** | 新增（M21.4 要求） |
| **D4** | `Other` 行 = **当普通一行参与翻页**，排在所有扫描结果之后 | owner 本轮选定（⛔ 推翻了 AI 推荐的「固定列表底部不翻页」）。**已知代价**：网络多时 `Other` 落在第 N 页，与客户原话 `at the bottom` 找不到的原始场景同构 —— owner 已知情选定 | 新增（AI 本轮 probe 发现，gate 未覆盖） |
| **D5** | 「隐藏网络不持久化」**如实告知**，落点 = **连接成功的 Message 里**，⛔ 不做表单常驻 hint | AI 定 + owner 未否；判据：项目硬规则本就要求提交后必给成功/失败 Message ⇒ 免费搭载、不吃 320 高的垂直空间 | §6-⑤ |
| **D6** | **本期不新增 disconnect / forget 入口**；改为依赖「连上隐藏 SSID 后自动重新扫描」，让该 SSID 以已连接态进列表，✕ 免费继承 | Config-T 8.4 build 28 已有同一做法（bonniezhou 逐字 `b. Automatically scan after connecting to a hidden SSID.`）⇒ 四面一致且有先例 | §6-⑥（含撤销其错误前提，见 §2） |
| **D7** | 键盘 = **组件级复用** file-local `Keyboard` (`5318:294`) + `Key` (`5315:22601`)，⛔ 不新造键盘 | 实测键位含 Shift（大小写）· `.?123`（数字符号）· 眼睛图标（明文回显）—— SSID 录入所需全覆盖 | §6-⑧ |
| **D8** | 表单页画**两个状态**：① 表单态（三字段 + 底栏 `OK`+`Home`）② 录入态（字段 + 键盘，**无底栏**） | 既有 `WIFI/Enter Password` (`5324:2618`) 实测无底栏、键盘替代底栏、提交靠键盘上的 `Join` | 新增 |
| **D9** | 落点 = **新建独立 page**，但从 V4-1535 page clone 键盘与状态帧作起点 | §M45.1「全新需求 → 新建独立 page」；clone 走 §M42 gate + §M46。⛔ 不并进 V4-2318（那是 Hotspot 模式单）、不污染 V4-1535 已交付 page | §6-⑩ |
| **D10** | 表单页导航标题 = **`Other`**（单词式） | §M21.4 两级先例搜索：最近邻 sibling = WiFi 页 `8606:58` 用单词式 `WiFi`。⚠️ 本产品标题范式**三分**（见 §3 债务）| 新增 |
| **D11** | 表单页字段行行高 = **46**（⛔ 不是 canonical 的 42、不是列表的 36）| §M21.4 两级先例：最近邻**同场景**页 = `5324:2618`（WiFi 凭据录入），实测字段行 `Frame 1983` 448×**46**。**附带收益**：46 ≥ 44 ⇒ 同时满足 `lcd-pickup.md:147` 的「最小点击区 ≥44px」，而 42 与 36 都不满足 ⇒ 本轮不再继承那条 2px 矛盾 | 新增（解掉 §4 债务 3）|
| **D12** | 明文切换图标 = clone 既有 instance **`icon/Preview/Show`**（`5325:19657`，24×24）| 同文件现成 instance，走 §M42 clone；⛔ 不自画眼睛图标、不用 Unicode | 新增 |
| **D13** | 成功文案定稿 = **`Connected to Guest_Hidden — reconnect after reboot.`**（⛔ 不是初稿的 `…this connection won't survive a reboot.`）| **实测选定**：三个候选逐个量宽 —— 定稿版 51 字符 = **415px**（装进 480 且单行不折行）；初稿版会撑到 480 铺满并折成 2 行。且 `reconnect after reboot` 是**可操作指引**，优于只陈述限制 | 落实 D5 |
| **D14** | Message 宽度走 **HUG**（⛔ 不铺满帧宽）| §M37.3 先例：文案常驻页 `10166:2` 既有两个 instance 实测 `sizing=["HUG","HUG"]`、宽 230 / 260、`relY=8` ⇒ 本产品范式是**短句 hug toast**，不是 banner | 新增 |
| **D15** | Message 必须 `layoutPositioning='ABSOLUTE'` 才能落位 | 实测：LCD 帧根 frame 是 **VERTICAL auto-layout**，直接 `appendChild` 会被排进流内（设 `y=8` 实得 `y=326`）。⚠️ 这条对后续所有浮层帧（F/H）同样成立 | 新增（施工陷阱）|
| **D16** | 表单行间 = 内容区 `gap=0` + 每行**底部 1px `#252525`** 分隔线 | 组合来源：行高 46 取键盘页（同场景），行间处理取 canonical 设置页 —— 键盘页只有一行字段，看不出行间该怎么处理 ⇒ 各取其适用面 | 新增 |

---

## 1b. owner 2026-09-10 追加拍定 —— ✅ **2026-09-10 已全部在 Figma 落地**

| # | 决策 | 影响面 | 推翻了什么 |
|---|---|---|---|
| **D17** | 🔴 **隐藏 SSID 支持无密码** ⇒ `Security` 从只读标签改为 **二选一（`WPA2` / `None`）**，选 `None` 时 **`Password` 字段隐藏** | ⛔ **推翻 D2 / D3**（只读标签作废）· 触发 **§M17.1 选项列表 canonical**（须建绿框面板 + 被编辑行加框 + 矢量选中标记，取值见 `lcd-canonical-spec.md` §2）· 表单帧多一个状态（Security 面板展开）· 再多一个状态（选 None 后密码字段隐藏）· PRD §Acceptance 第 2 条与 UX 卡 Acceptance 第 2 条都要改 · `lcd-message-strings.md` §4.1 那条「passphrase 必填」判据要改 | **P1 已解**（owner 答「支持无密码」）⇒ 三条硬约束里「无无密码模式」这一条**不成立**，design-record §2 / §4 的相关表述须订正 |
| **D18** | 提示落位从「距帧顶 **8px**」改为 **距顶 24px** | 三个含 Message 的帧（connecting / 成功 / 失败）· `lcd-message-strings.md` §4.2 落位行 · UX 卡 Acceptance 第 5 条 · handoff §5.3 已知偏差那条可撤 | **P7 已解**；⚠️ 24px 是否足以避开 46 高的导航条须实测（46 > 24+45 ⇒ 仍会压，**下轮必须量**，可能要继续下移或改落位到内容区顶部）|
| **D19** | 表单页导航标题改 **路径式 `WiFi/Other`**（owner 逐字「如果是在 Other 页面，导航条应该包含 WiFi」）| D 帧 / E 帧 / C 帧 / F 帧 / H 帧 五个表单态帧的导航标题 | ⛔ **推翻 D10**（单词式 `Other`）。⚠️ 同时意味着**本产品标题范式之争有了 owner 口径 = 路径式**（与 canonical `8878:2` 的 `Settings/Video Encode` 一致）⇒ §4 债务 1「标题范式三分」应记为「owner 已定路径式，WiFi 页 `8606:58` 的单词式属存量待收敛」|

### 1b-1. 落地结果（2026-09-10 第二轮，逐条实测）

| # | 落地物 | 实测读数 |
|---|---|---|
| **D17** | `Security` 行加 canonical 下向三角（clone `8878:21`，14×7.909 `#f1f1f1`）于 **C / F / H** 三帧（`10398:850` / `10398:851` / `10398:852`）；值本来就已是 `#ffffff` ⇒ 符合 canonical 枚举下钻行 | 三角落在右控件容器末位，值→三角 gap 16，右缘齐 456 |
| **D17** | 新帧 **C2 `10398:853`**「Security options open」：clone canonical 面板 `5314:9564` 裁到 2 行（当前值 `WPA2` 36 高 + 普通行 `None` 35 高）⇒ 面板 **240×71**，落 (216,152)，右缘齐被编辑行 456 | 面板 152..223 · 被编辑行 106..152 · 两者在 y=152 连体 |
| **D17** | C2 的**连体绿框** `10401:874`：阶梯 VECTOR 6 点闭合路径，节点原点 = bbox 各轴最小值 (24,106)，`432×117` | `M 0 0 L 432 0 L 432 117 L 192 117 L 192 46 L 0 46 Z` · `vectorPaths.length=1` |
| **D17** | C2 被编辑行的值容器 `Group 3` 设 `visible=false` —— **照 canonical**（`5314:9559`/`5314:9554` 实测均 `hidden:true`，值由面板绿色当前值行承载） | — |
| **D17** | 新帧 **C3 `10398:908`**「Security = None (no password)」：`Security` 值改 `None`，`Field row / Password` 设 `visible=false` | 可见行 2 条：60..106 / 106..152 |
| **D18** | 三帧 Message 落位（`10360:831` / `10353:4826` / `10361:735`）**终值 `y=54`** | 演进：`8`（原规则，压导航 38px）→ `24`（D18 初值，**实测仍压 22px 且把标题横切成半截 ⇒ 作废**）→ **`54` 定稿**（导航条 46 + 8）。三帧实测 `54..99`，导航重叠 **0**，完整落在内容区（54..274）内。**owner 2026-09-10 二次拍定：改为按落位通则走**，见 `lcd-message-strings.md` §2.5 |
| **D19** | 五帧导航标题 → 路径式 `WiFi/Other`（`10350:288` `10358:441` `10359:526`→`10359:551` `10360:667` `10361:706`） | Roboto/Bold 20 `#7ed321`，文本宽 50→**97**，右缘 149 ≪ 导航条 480 ⇒ 不挤压 |
| 连带 | 新增 3 条流程连线：`C-to-C2`（tap Security）· `C2-to-C3`（select None）· `C3-to-connecting`（tap OK, no password） | 11 条连线全绿：正交 0 违例 · 锚定 0 fail · 标签间距 0 fail（max 57 ≤ 60） |
| ~~连带~~ | ~~第二个 `Mark area` 圈住 C 帧 `Security` 行~~ | 🔴 **已随整个 Change Log 一并删除**（owner 2026-09-10 拍定，见 §1b-3）|
| 连带 | Journey 卡补 **P2 远程支持 / P3 现场工程师** 两行 persona lens（`10411:875` / `10411:888`）+ meta 行改三 persona | F2-late 的 ≥2 persona 前置已满足 |

### 1b-2. 本轮抓出的两个真错（都不是机检能抓的）

| # | 错 | 怎么发现 | 修法 |
|---|---|---|---|
| **E1** | 失败提示的文字被绑成 **`UX/Blue/Default` `#3892f3`**（info 蓝），而库里 `status=error` 主组件绑的是 `UX/Red/Default` `#ea4233` | **只有渲染图能看出来**（背景粉 + 图标红 + 文字蓝）。五闸全绿，`colors` 闸也不报——因为它是合法的变量绑定，只是绑错了那个变量 | 逐 instance 与其 `getMainComponentAsync()` 的同名文本节点比对 `boundVariables.color`，不一致的重绑回主组件的 token。info / success 两条比对后本来就对 |
| **E2** | `node.clone()` 把 C2/C3 建到了 **PAGE 上而不是 Section 里** ⇒ 页面坐标 3020 ≠ Section 相对 3020，两帧实际压在 D/E 帧上 | 我第一次的碰撞检查**混用了两套坐标系**（新帧读 page 坐标、旧帧读 section 坐标）所以判成「无碰撞」；`overlap` 机检也漏了，因为它**只比同一 SECTION 的直接子节点**，跨 parent 不比 | `sec.appendChild()` 显式收进 Section 后再设坐标；并把碰撞检查改成**统一从 `sec.children` 读**，一套坐标系 |

**⇒ 回流候选（判为 DS 档，见 §9）**：clone 的落点不可假设（Q15 的延伸）· `overlap` 闸有 parent-scope 盲区 · 变量**绑错**与变量**未绑**是两类问题，只有前者机检看不见。

### 1b-3. owner 2026-09-10 第三次拍定（走查后追加）

| # | 决策 | 落地 | 推翻了什么 |
|---|---|---|---|
| **D20** | 🔴 **整个 Change Log 模块删除** —— `Mark area` `10390:272` + `Mark area` `10406:874` + `Description_text` `10391:237` 三个节点全删 | ✅ 已删，Section childCount 60→57，`Mark area/Description_text/Change Log` 残留扫描 `[]`，`overlap` 那 2 条设计意图 findings **一并清零** | ⛔ **推翻 skill §6-JIRA.W 的「⑦ Change Log 注释是每档都要的」**。owner 逐字质疑：「已经有 PRD、UX 交付 和用户体验地图，为啥还需要增加 Change log 这个模块？」<br>**判据**：⑦ 这条规则源自 owner 在 **V4-2402（W1 档，无卡族）** 的反馈，当时 Change Log 是「改了哪里」的**唯一**载体。本单是 **W3 档**，PRD 卡 + UX 卡 + Journey 卡 + BEFORE/AFTER 分属两 Section + 11 条流程连线已把 delta 定位清楚 ⇒ Change Log 边际价值只剩橙色虚线框，代价是恒产 2 条 overlap findings 要每轮解释。**⇒ 「⑦ 每档都要」在 W3 档不成立，回流候选 R6** |
| **D21**<br>⚠️ **2026-09-11 收窄** | **顶部提示落位改为通则驱动**，不再逐单定数字：**提示上缘 = 承载「我在哪」的顶部区域下沿 + 8px** ⇒ 设置页族 `y=54`、首页族 `y=8`。<br>🔴 **设置页那一档已加前提**：「导航条正下方**不是**这条提示所指代的状态控件行」；是的话改盖标题、保控件（`y=8`）。真源 = [`lcd-message-strings.md` §2.5.1](../specs/lcd-message-strings.md)。<br>⚠️ **本条当时就自相矛盾，值得记一笔**：右栏自己写了「全文件 8 处既有 toast 全部 `relY=8`，其中 V4-2333 L6/L7 与本单完全同构、那一轮定稿就是 y=8 标题全盖」，却仍得出「设置页族 `y=54`」，并反过来把那两帧登记成存量不合规（P24）。⇒ **手里的先例证据与结论冲突时，先解释冲突再定规则**，别把冲突的那几个先例改判成违规。 | ✅ 通则已写入 `lcd-message-strings.md` **§2.5**（含 8 处先例实测表）；本单三帧落 `y=54` | ⛔ **推翻 D18 的 24px**。owner 逐字：「可参考其他页面的顶部提示的位置，或者你给我一个触摸屏上顶部提醒消息的位置的距离的建议，后续都按照这个来」<br>**实测推翻依据**：全文件 8 处既有 toast **全部 `relY=8`**，其中 **V4-2333 `9988:423`/`9988:690`（L6/L7）与本单 F/G/H 完全同构**（46 高导航条 + 20px 路径式标题 + 45 高 toast），那一轮定稿就是 y=8、标题全盖 ⇒ 「压导航条」在本文件**不是新问题而是既有形态**；而 24 是三档里**唯一把标题横切成半截**的值、且无任何先例 ⇒ 最差档 |
| **D22** | **交付验证不再搭本地证据页** | ✅ 证据页与本地服务已停并删除（连带清掉上一轮遗留在 8899 的老服务，PID 70401）| owner 逐字选定「直接给 Figma 链接，不做证据页」。⚠️ **与 CLAUDE.md 那条「要我做视觉判断就起服务给可点链接」冲突** —— 属 owner 显式豁免本项目此类任务，⛔ 别再自动搭页；⚠️ 代价：并排对比与「我自己先看过」这两层保障没了，owner 自己在 Figma 上看 |

### 1b-4. owner 2026-09-11 第四次拍定 —— 🔴 **D23 推翻 D17**（本轮已全部落地）

| # | 决策 | 落地 | 推翻了什么 |
|---|---|---|---|
| **D23** | 🔴 **`Security` 不是用户可编辑字段，整个不出现在表单里**；**有密码 ⇒ 出现密码步骤**并在其内容区首行写明 `WPA2-PSK`；**无密码 ⇒ 不出现密码步骤**，提交网络名后直接进 connecting | 见下方落地表 | ⛔ **推翻 D17 / D11 的三字段形态**。owner 逐字两句：「目前只有 WPA2 这种类型，而且不是可编辑的，直接在输入密码的时候提醒是 WPA2」+「无密码根本不会弹出输入密码框；有密码时就是 WPA2的」 |

**为什么这次才闭合（⛔ 别再把 youngzhang 那句当二选一的依据）**：`we only have WPA and no password mode for hidden SSID` 的两种读法（「WPA + 无密码两种模式」vs「只有 WPA，且无密码模式」）**两种模式都真实存在**，但**不由用户在 UI 上选** —— 后端探测后决定要不要要密码。⇒ D17 把它做成 UI 二选一是**过度外推**（把「后端有两种模式」直接等同于「用户要选一种」）。

**范式来源（实证，不是推断）**：Config-T `rJJjWWs51n2iFOlCIC7aYG` 的同一功能演进史 ——

| 版本 | 帧 | 高 | `Security:` 行 |
|---|---|---|---|
| 旧版 | `892:5319`「2.1 Connect the WiFi」| 487×**310** | **可见** |
| 2025-11-06 改版（page `4900:61499`，标题即 `Change the WiFi security value from WPA-PSK to WPA2-PSK`）| `4900:61500` | 487×**254**（矮一行）| **`effVisible: false`**，加密类型折进标题句 `Enter a WPA2-PSK password for “WiFi_name_3”` |

且 Config-T 的密码框只在**有密码**的网络上出现（`1.3 locked & connected` 系列），开放网络不弹 ⇒ 与 owner 两句逐字吻合。**⇒ 本单按此收敛即「四面一致」（P4）**，不是新发明。

#### 落地结果（2026-09-11，逐条实测）

| 动作 | 节点 | 实测 |
|---|---|---|
| C 帧隐掉 `Security` + `Password` 两行 | `10351:2967` / `10351:2974` → `visible=false` | 内容区 `10350:289` 可见行 **1**（`Network name`）；节点保留不删，照 Config-T `4900:61500` 的可逆做法 |
| **F / H 两帧同样隐掉**（⚠️ 差点漏，见下） | F `10360:676`/`10360:683` · H `10361:715`/`10361:722` | 五个含表单的帧可见行数：C 1 · D 1 · E 2 · F 1 · H 1 |
| E 帧加内联提示行 | 容器 `Hint row / Security type` **`10463:864`** + 文本 **`10463:865`** | `Enter a WPA2-PSK password for "Guest_Hidden"` · 16px `#7ed321` · 文本宽 **342** · 容器高 **32** · 内容区 90−padding 12 = 78 = 32+46 ⇒ **overflow 0** |
| 删 C2 + C3 + 三条连线 | `10398:853` · `10398:908` · `10403:874–885`（12 件）| 共删 **14** 个节点；Section childCount 57 → 43 |
| 新增「无密码」分支连线 | `10464:1345`（线 1240×92 @900,360）· `10464:1346`（箭头 10×8 @895,452）· `10464:1347`（点 6×6）· `10464:1348`（标签 @1460,375）| 路径 `M 1240 0 L 1240 50 L 0 50 L 0 92`（D 底边 → y=410 走廊 → F 顶边）· 标签距线 **8px** · 四件 `parent.type='SECTION'` 已复验 |
| 两条标签改文案 | D→E `10383:857` = `has password / 有密码` · E→F `10386:849` = `submit with Join / 按 Join 提交` | 后者顺手修了既有错误：键盘态**没有底栏**，提交靠 `Join` 不是 `OK`（§4 债务 5 早已登记双轨，但标签写错了）|
| 连线总数 | 11 → **9** | B-to-C · C-to-D · D-to-E · **D-to-connecting(新)** · password-to-connecting · connecting-to-success · connecting-to-failure · success-to-steady · failed-to-retry |
| Section 收紧 | UX 卡 `10370:838` x 4220→**3020** | Section **4940×1704 → 3740×1677**（maxR 3700 / maxB 1637）· blockPairs 0 · labelVsBlock 0 · outOfBounds 0 |

#### 本轮抓出的三个「机检抓不到」的问题

| # | 问题 | 怎么发现 | 性质 |
|---|---|---|---|
| **E3** | **F / H 两帧的 `Security` + `Password` 行还是可见的** —— D17 当初给 **C/F/H 三帧**都加了三角，改 C 时只想着「表单页」 | 按 §M-DISCIPLINE.SCOPE 用**对象全集**扫（`findAll` 全部 `Field row /` + 逐帧 effVisible），而不是改我记得的那几帧 | 差点交付出「同一个表单在三帧里长得不一样」的自相矛盾稿 |
| **E4** | **文案常驻页卡 `10394:54` 还写着「8px from the frame top」** —— D21 已作废的落位 | 上一轮的旧措辞扫描**只扫了 feature Section**，没扫常驻页 Section `10167:2` | 上一轮的「零残留」结论**scope 不全**；本轮改成两个 surface 都扫 |
| **E5** | **常驻页卡 `Jira V4-1646` 是纯文本没超链接**（违反 §M23.8.1） | 机检 `source-link-integrity` 报的 —— 上一轮 handoff 记的「`--node 10167:2` 三条规则全过」**不成立** | 已修：两处 `V4-1646` + Slack 频道名都加了 hyperlink + `#33A4FD` + 下划线（两个信号都要）|

#### 顺带修掉的一个**我自己造成**的伤（R8 的来源）

改日期戳（`2026-09-10`→`11`）时用「等长替换 + 逐段回贴」，结果 UX 卡与 Journey 卡的**整条 meta 行都变成了超链接**。
根因：`n.characters = …` 会让整串**继承第 0 个字符**的 `hyperlink` / `textDecoration`，而我的逐段回贴**只加不减** ⇒ 非链接段上继承来的链接没人清。
PRD 卡同样操作却没事 —— 因为它第 0 个字符是 `P`（`PRD · `）本来就没链接。**⇒ 判据不能靠「哪个节点没出事」反推安全**。
修法：`setRangeHyperlink(0, len, null)` + `setRangeTextDecoration(0, len, 'NONE')` **先全清再逐处加**。已复验两条 meta 行只在两处 `V4-1646` 上带链接与下划线。

---

## 2. 本轮撤销 / 修正的既有结论（⛔ 别再引用原文）

| 原结论 | 出处 | 撤销理由（本轮实测） |
|---|---|---|
| 「**AI 改不了 LCD 按钮文案**，Verdana 在 MCP 不可写 ⇒ 只能出待改清单交 owner」 | gate §3.1② / `PRODUCT_INTRODUCTION.md:99` / 本计划原 P8 | **🔴 实测推翻**。走 §M47.2「整段 `setRangeFontName` 覆盖 → 赋 characters」，`Scan` → `OK` 一次成功（`Verdana/Regular@15` → `Roboto/Regular@15`，节点 `10350:314`）。同法已成功改动列表行 SSID 名（`Helvetica/Bold` → `Roboto/Bold@14`）与导航标题（`Verdana/Bold@20` → `Roboto/Bold@20`）。⇒ 真正的代价**不是「改不了」，而是字体族被换成 Roboto**（同帧 `Home` 仍 `Verdana/Bold@15`）。若必须保住 Verdana，才需要 owner 在 Figma 客户端手动改。**⛔ 后续别再把按钮文案排成「AI 不可完成」** |
| 「LCD 无 forget / disconnect 入口」 | gate §1.3c / §6-⑥ | **半错**。① LCD WiFi 页 `8606:58` 实测：已连接行右侧**有 ✕**（`icon/Edit/Close`），未连接行无。② youngzhang 那句 `no disconnection button is also a bug` 带限定 **`for this case`** = 隐藏 SSID 场景，不是列表整体。③ 讲 ✕ 最细的那条记录（bonniezhou 2026-07-10「remove 悬停 × 仅历史网络 / Disconnect 仅已连接时显示」）说的是 **Config-T `wifi.vue`**，不是 LCD。⇒ 真问题是「隐藏网络扫不到 ⇒ 没有行承载 ✕」，由 **D6** 解 |
| 「不持久化」的 scope 未明确区分 | gate §1.3b | **补齐**：仅针对隐藏 SSID。youngzhang 两句主语均显式限定 `hidden SSID hotspot info` / `hidden hotspot information`，无全集词；旁证 bonniezhou 把「隐藏 wifi 记不了密码」当**例外**单列。⇒ 普通 WiFi 走 `Remember this network` 勾选才持久化，隐藏 SSID 是**连勾选机会都没有** |
| 隐含「8.4 会修掉持久化」 | 易从 young 的 `No, this has always been the case` 误读 | **明确否**：该 `No` 字面自相矛盾，语义是「不是 8.4 新引入的」。8.4 只承诺「LCD 加 Other」，**无任何一句**承诺修持久化 |
| `5315:9602` = 「WiFi 密码键盘帧」 | gate §3.2 / 项目 audit 表 | **纠正**：它是**一整个 page**（canvas），名 `< V4-1535 > Virtual keyboard for configuring WiFi password on the touch screen 20250721`，含完整 WiFi 流程帧 + 键盘 component set |

---

## 3. 剩余待核 / 待确认项（⛔ 不自行填平）

| # | 项 | 归属 | 阻塞什么 |
|---|---|---|---|
| ~~**P1**~~ | ✅ **已解（owner 2026-09-10）**：按「只有 WPA 和 无密码 两种」解 ⇒ **D17**。D2/D3 只读标签方案作废；已落地二选一 + 密码字段条件显示 + 两个新状态帧 | 已答 | — |
| **P2** | 成功 Message 说两件事 vs `lcd-message-strings.md` §2.4「一条提示只说一件事」。本轮解法 = em dash 单句让「临时」成为同一事实的限定，**定稿串（D13）= `Connected to Guest_Hidden — reconnect after reboot.`**（2026-09-11 订正：此处原引的 `…this connection won't survive a reboot.` 是初稿，D13 已推翻，⛔ 别再引用）| **owner 追认** | 判为违反则退回「表单上方常驻 hint」 |
| **P3** | 目标版本是否 8.4（Jira 无 fixVersions，与 Slack 承诺矛盾）| owner | 排期，不阻塞画图 |
| **P4** | 「四面一致」（LCD / Hotspot phone / WebR ConfigT / CC ConfigT）是否本单验收口径；要否拆单 / 建 issuelink | owner | 验收口径，不阻塞画图 |
| **P5** | `wifi_module_mode` = Disable / Hotspot 时 `Other` 隐藏 / 置灰 / 照常可点（V4-2318 决策 hide-not-dim 是 Config-T convention，LCD 侧当时标「需验证」）| owner + 后端 | 是否多画一个边界态帧 |
| **P6** | 要否顺手关掉 V4-1865 那条 TBD（`F2/F3 内部 SSID list 是否深改`）| owner | 旧取舍翻案 |
| **P7** | 本仓无 `docs/product-context.md` ⇒ gate 的 `data_feasibility` 恒 SKIP。要否补建 | 主线登记项 | 仓级基础设施，不阻塞 |
| ~~**P8**~~ | ~~底栏 `OK` 文案 = owner 手动项，AI 改不了~~ → **🔴 本轮实测推翻** | — | — |

---

## 4. 既有债 / 已知偏差（如实登记，本轮不修）

1. ~~**标题范式三分**~~ → **owner 已定路径式（D19，2026-09-10）**。本单五个表单态帧已改路径式 `WiFi/Other`，与 canonical `8878:2` 的 `Settings/Video Encode` 同源。**剩余存量待收敛**（⛔ 本轮不动，也不属本单 scope）：WiFi 页 `8606:58` 的单词式 `WiFi` · 键盘页 `5324:2618` 的句子式 `Enter the password for "Wifi_name_3"`。⇒ 债的性质从「范式之争无口径」变为「口径已定、存量未收敛」，收敛动作需 owner 单独立项。
2. **行高三分**：canonical 设置页 **42**（`lcd-canonical-spec.md:22`）· WiFi 列表 legacy `WiFi_item` 实测 **36** · 键盘页字段行 `5324:2618` 实测 **46**。本轮 `Other` 行跟 sibling 走 36，表单页字段行按 **D11** 走 46。⛔ 本轮不统一，如实登记。
3. ~~**≥44px 点击区 vs 行高 42/36**~~ → **本轮已避开**：按 D11 取 46 ⇒ 满足 `lcd-pickup.md:147` 的 ≥44px。⚠️ 但该矛盾**在 canonical 设置页（42）与 WiFi 列表（36）上依然存在**，只是本单的可点输入字段不再继承它；⛔ 不自行改 canonical，登记待 owner 独立处置。
4. **字体族不一致**：LCD 产品帧既有文字为 Verdana，`use_figma` 环境 `listAvailableFontsAsync` 不返回 Verdana ⇒ 新建文字用 Roboto。handoff 必须如实记，**⛔ 禁表述为「字体已统一」**。
5. **提交键双轨**：键盘内 `Join`（组件自带）vs 底栏 `OK`（项目硬规则）。判为不同层、不冲突，但显式登记。
6. **`WiFi_item` 是 legacy 组件**：V4-1865 handoff §3.4 逐字「F2/F3 内部 SSID list 故意不深改」。本轮只在其上加一行 `Other`，⛔ 不深改该组件。**实测补充**：它是带 `Status` 轴的 component set（`Status=Normal` `5324:1934` / `Status=Connected` `5324:1966`），已连接态靠**切变体**而非隐藏子层；`Status=Normal` 变体内的 `icon/load/loading 2` 虽 `visible=true` 但渲染为空，只占 22px 缩进位。
7. **字体族三分（本轮扩大）**：同一 LCD 帧内实测并存 **Verdana**（导航标题、`Home`）· **Inter**（模块行）· **Helvetica**（列表行 SSID 名）。凡本轮改动过文案的节点一律转 **Roboto**（Verdana / Helvetica 在 MCP 环境 `listAvailableFontsAsync` 均不返回，实测 `verdanaAvailableInEnv: []`）。⛔ handoff 禁表述为「字体已统一」。
8. **占位符 `opacity 0.2`**：字段行占位符实测为白色 `#ffffff` + **opacity 0.2**（不是灰色字），在 `#313131` 上对比度很低。沿用键盘页 `5324:2618` 既有取值，⛔ 本轮未自行调整；可访问性问题登记待 owner 独立处置。
9. **成功提示盖住导航条**：Message 按项目硬规则落「水平居中 + 距帧顶 8px」，实测 415×45 的提示条会**完全覆盖 46 高的导航条**（只剩左侧一角返回箭头）。⚠️ 这是规则的固有结果而非施工失误 ⇒ 已在 review 页列为 owner 判定项（下移到内容区顶部 / 保持）。

---

## 5. 复用来源登记（宿主范式来源，§M17 Acceptance 要求）

| 用途 | 来源 node | 说明 |
|---|---|---|
| WiFi 列表页宿主范式 | `8606:58` | V4-2318「B · WiFi page (Module 2 — Hotspot module as WiFi)」480×320 |
| 列表行组件 | `WiFi_item` instance（`8606:90` 等，容器 `8606:89` 432×163，5 位第 5 隐藏）| 行高 36；子层 ✓`icon/Edit/Selected` · ✕`icon/Edit/Close` · `Icon/Lock` · `Icon/Wifi/3` · hidden `Label/Default` · hidden `icon/loading 3` |
| 设置页 canonical | `8878:2` | 行高 42 / 路径式标题 / 下向三角 `8878:21` |
| 键盘 component set | `Keyboard` `5318:294`（`Type=Normal` `5315:21609` / `Type=Active` `5315:22745`，480×164）| file-local |
| 键组件 | `Key` `5315:22601`（`Status=Normal\|Active` × `Type=Shift\|Delete\|Character`）| file-local |
| 密码录入范式帧 | `5324:2618` 空态 / `5325:19324` 已输入态 | 含眼睛图标明文切换、按键放大气泡 |
| 既有 WiFi 状态帧（可 clone 起点）| Connecting `5325:18527` · Connected `5325:18721` · Disconnected `5326:116080` · loading `5326:154148` | 均 480×320 |
| 底栏按钮 | file-local `LCD Button` `4518:3244`（key `6ddb4464c0b1ea41d867f75a9841c13dc9effc29`）| `OK` = `Type=Primary` + 文本覆盖 |
| Message 组件 | 库 key `e9574b39e93ac3ffe94834f05d704798ce997274` | `status`(success/info/error/warning) × `size`(L/M)；L = 点击关闭 |
| Jira requirement | file-local key `e8604a08a31c8c17cb8aec35d7692e88965485e7`；clone 源 `5315:19564`(V4-1535) / `5356:4431`(V4-1542) / `5392:17702`(V4-1543) | ⛔ 跨文件 import 会 fail，必须文件内 clone |
| 文案常驻页 | page `10166:2` / Section `10167:2` | 新串必须同步落此页 + `lcd-message-strings.md` |

---

## 5b. 外部真源链接登记（2026-09-10 实测取值，PRD §需求来源 直接引用）

**Jira V4-1646 实况**（`getJiraIssue` 直读，⛔ 不走 JQL —— 本项目已实证 JQL status 滞后）
cloudId `4e59bbf6-517e-4d1f-96c8-ea0e5a343857` · <https://tvunetworks.atlassian.net/browse/V4-1646>

| 字段 | 值 |
|---|---|
| summary 原文 | `The Wi-Fi function is missing the 'Other' option.` |
| status / priority / type | `Backlog`（statusCategory=In Progress）/ `Medium` / `Bug` |
| fixVersions | **`[]` 空** ⇒ 与 Slack 的 8.4 承诺矛盾（P3）|
| labels | `["GUI"]` |
| **assignee** | **Nancy Zeng**（`5e7aefff2466490c496f7aa7`）⇒ ⚠️ 交付后必须转 **Edward Wu**（V4 LCD 归属，`design-process.md:208`）|
| reporter | winni（`609b6e5320ad1b0070d860fb`）|
| issuelinks | **`[]` 空**（artifact 记录经核实仍成立）⇒ 三个背景单需在 PRD 显式列出，靠 issuelinks 采不到 |
| 评论 | 5 条（末条 id `252625`，winni 贴 Slack 链接）|

**Slack 真源**（频道 `#tvu-support-global-requests` = `C014Y5SA4VA`，主帖 89 回复）

| 用途 | 链接 | 来源性质 |
|---|---|---|
| thread 主帖（Susumu，2026-07-10 13:21:27）| `https://tvunetworks.slack.com/archives/C014Y5SA4VA/p1783660887257889` | ✅ 工具原返回 permalink 字段 |
| **最强引用**：Susumu `Please consider to add LCD/Other(Hidden SSID) feature.` | `https://tvunetworks.slack.com/archives/C014Y5SA4VA/p1783673699149789` | ✅ **非构造** —— winni 亲自贴在 V4-1646 评论 `252625` 里，有第三方书面证据 |
| winni `Yes, we will add this function on 8.4.` | `.../p1783673977167789` | ⚠️ 按规则构造（工具对回复只返回 ts）|
| youngzhang `Yes, we only have WPA and no password mode for hidden SSID` | `.../p1783663014844789` | ⚠️ 构造；**这条是 P1 歧义的原句** |

> 🔴 **纠错**：早前一轮 subagent 提供的 `1783672172.048409` **不是**主帖 ts（那是 `#prod_tm1000_v4_dev` 另一条 thread）。主帖真值 = `1783660887.257889`。⛔ 别再引用前者。

**三个背景参照单**（`getJiraIssue` 直读；⚠️ 均 fixVersions 空）

| Key | summary 原文（⛔ 引用照抄，勿自行简称）| status | assignee |
|---|---|---|---|
| V4-1535 | `Virtual keyboard for configuring WiFi password on the touch screen` | Done | Asher Guo |
| V4-1865 | `Enable Reuse of TM1100 Pack's Second Internal WiFi Module for Additional WLAN Connection On Config-T` | Done | Bonnie Zhou |
| V4-2318 | `CLONE - Enable Reuse of TM1100 Pack's Second Internal WiFi Module for Additional WLAN Connection On LCD Screen` | Resolved | Edward Wu |

---

## 6. 帧清单（要画的状态全集）

| # | 帧名 | 内容 | Section |
|---|---|---|---|
| A | `BEFORE · WiFi list` | clone `8606:58` 现状，无 `Other` | BEFORE |
| B | `AFTER · WiFi list (last page)` | 末页显示 `Other` 行（D4 参与翻页）| AFTER |
| C | `AFTER · Other form — empty` | **一个字段：Network name**（D23）；底栏 `OK`(Disabled)+`Home`。⛔ 不再有 Security / Password 行 —— 两行节点保留但 `visible=false` | AFTER |
| ~~C2~~ | ~~`Security options open`~~ | 🔴 **已按 D23 删除**（`10398:853`）—— Security 不可编辑 ⇒ 选项面板不成立 | — |
| ~~C3~~ | ~~`Security = None (no password)`~~ | 🔴 **已按 D23 删除**（`10398:908`）—— 无密码不是「选 None」而是「不弹密码框」 | — |
| D | `AFTER · Other form — network name input` | 键盘唤起录入网络名，明文，`Join` | AFTER |
| E | `AFTER · Other form — password input` | **仅在有密码时出现**（D23）。内容区首行 `Enter a WPA2-PSK password for "{SSID}"` + 密码行掩码 `********` + 眼睛图标 + 键盘 `Join` | AFTER |
| F | `AFTER · Connecting` | connecting 态（复用 `icon/loading 3` / 既有 Connecting 帧范式）| AFTER |
| G | `AFTER · Connected + message` | Message(success, L) 含 D5 那句；水平居中 + 距帧顶 8px | AFTER |
| H | `AFTER · Failed + message` | Message(error, L)；⛔ 不编失败原因，只说失败 + 下一步；字段保留、`OK` 保持可点 | AFTER |
| I | `AFTER · WiFi list (connected)` | 隐藏 SSID 自动重扫后以 ✓ 已连接态进列表，带 ✕（D6）| AFTER |

~~条件追加：P1 答「支持无密码」⇒ 加 Security 二选一面板帧 + 密码字段隐藏态帧~~ → ~~已落地为 C2 / C3（2026-09-10）~~ → 🔴 **两帧已按 D23 删除（2026-09-11）**。剩余条件追加：P5 定「隐藏/置灰」⇒ 加 `wifi_module_mode` 边界态帧。

**帧总数 8**（10 − C2 − C3），布局 = 行 1 四列（B · C · D · E @ x 780/1340/1900/2460）+ 行 2 四列（F Connecting · G Connected · I Steady · H Failed @ 同 x）。UX 交付卡左移到 `x=3020`，Section 收到 **3740×1677**。

~~**帧总数 10**（原 8 + C2 + C3），行 1 六列，UX 卡在 `x=4220`，Section 4940×1704~~ → 🔴 **已被 D23 取代，见本节末尾的现行数字**（C2/C3 已删 ⇒ 8 帧 / 行 1 四列 / UX 卡 3020 / Section 3740×1677）。

---

## 7. 阶段执行计划

- [x] **Stage 0** 本计划文件（回填 upstream-gate artifact 仍待做）
- [x] **Stage 1** M0 mapping table → owner 2026-09-10 确认「开建」
- [x] **Stage 2** 建 page ✅（`10340:2`，落 index 4 = `To be confirmed` 正下方，画布底色照 V4-2333 sibling `0.4176/0.4152/0.4152`）→ **10 帧全部画完**

  🔴 **2026-09-11 第三轮起手复验后订正**（原文写「四段 Section + 已画 4 帧、待方向确认后铺剩 5 帧」，两处都已过时）。page 实际顶层只有 **3 个节点**：

  | 顶层节点 | id | 几何 | 内容 |
  |---|---|---|---|
  | Section `BEFORE` | `10343:3` | (680,0) 600×420 | 1 帧（A）|
  | Section `< V4-1646 > WiFi Other (Hidden SSID) on LCD` | `10343:4` | (1360,0) ~~4940×1704~~ → **3740×1677**（D23 后收紧）| ~~57~~ → **43 子节点** = **8** 产品帧 + 3 张卡 + 32 个连线部件（**9** 条 × 4 件）|
  | `Jira requirement / V4-1646`（INSTANCE，page 级）| `10378:2960` | (1360,−560) 2400×372 | — |

  ⇒ 原文记的 Context `10343:2` 与 UX Delivery `10343:5` **已不存在**（`getNodeByIdAsync` 均 `not-found`），交付卡现直接收在 feature Section 内。`sectionToSectionOverlap: []`。

  | 帧 | node id | 位置(rel) | 状态 |
  |---|---|---|---|
  | A · BEFORE 列表现状 | `10343:361` | BEFORE (60,60) | ✅ clone 自 `8606:58`，内容未动 |
  | B · AFTER 末页带 Other | `10344:144` | (780,40) | ✅ 3 结果 + Other，底栏反转为末页 |
  | C · Other 表单空态 | `10350:263` | (1340,40) | ✅ **一行** 432×46（`Network name`）· `OK`=`Status=Disabled`（D23 后）|
  | D · 网络名录入 | `10358:416` | (1900,40) | ✅ 键盘态、无底栏、`Join`，值 `Guest_Hidden` |
  | E · 密码录入 | `10359:526` | (2460,40) | ✅ 提示行 `10463:864` + 密码行 · 键盘 `Type=Active`，值 `********`（D23 后）|
  | ~~C2 / C3~~ | — | — | 🔴 **已按 D23 删除** |
  | F · Connecting | `10360:642` | (780,460) | ✅ 一行 · Message(info,L) `10360:831` @relY 54 · `OK`=Disabled |
  | G · 成功态 | `10353:278` | (1340,460) | ✅ Message(success,L) `10353:4826` @relY 54 |
  | I · 列表回显已连接 | `10362:720` | (1900,460) | ✅ `Scan`+`Home` 底栏 |
  | H · 失败态 | `10361:681` | (2460,460) | ✅ 一行 · Message(error,L) `10361:735` @relY 54 · 字段保留 · `OK`=`Normal`（可重试，刻意不禁用）|

  ~~**review 证据页**~~ → 🔴 **已按 D22 删除**（不再搭本地评审页，直接给 Figma node 链接）
- [x] **Stage 3** 交付层：PRD 卡 `10365:838`（现 680×1088 六段双语 + 5 处超链接）· UX 交付卡 `10370:838`（现 680×1625，6 张 navy chip）· Journey 卡 `10374:838`（现 1574×657 **真网格**，3 persona）· Jira 组件 `10378:2960` · ~~Change Log 注释~~ **已按 D20 删除**
- [x] **Stage 4** 流程连线 ×8（`connector/*`）—— 审计三项全绿：正交违例 0 / 锚定失败 0 / 标签间距失败 0。⚠️ 两条施工陷阱已回流 handoff §3（箭头必须独立节点 · 多段线节点 x/y 须设 bbox 原点而非起点）
- [x] **Stage 5** 文案入库两边同源：`lcd-message-strings.md` **§4**（新场景单元，四段 + `Trigger: user-initiated`；原 §4/§5/§6 顺延为 §5/§6/§7，文件头交叉引用同步改）+ Figma 常驻页新卡 `10394:40`
- [x] **Stage 6** 机检 + 落地文档
  - `--node 10343:4`：`bilingual-spacing` **PASS**（修掉 2 条 ZH opacity 0.315→0.45）· `overlap` 剩 1 条 = `Mark area` 圈选框盖 mockup，**已核归属为设计意图**（范式源 V4-2402 `10309:233`）· 6 条连线标签压帧已修（标签收到 gap 宽 80 并居中）
  - `--node 10167:2`：三条规则全过；⚠️ `overlap` `checkedUnits=0` = **无可判对象、不算通过**（§M-GATE-FALSIFIABILITY）
  - 存量债（**⛔ 勿逐节点修**）：`colors 324 / library-origin 113 / binding-fidelity 2337 / default-white-bg 284` —— file-wide owner-deferred（§M49.1）
  - [design-record](../specs/2026-09-10-v4-1646-lcd-wifi-other-design-record.md)（9 段）+ [handoff](../handoffs/2026-09-10-v4-1646-lcd-wifi-other-handoff.md)（含 M48 打勾表 + connector 审计表 + 机器输出原文）+ `REQUEST-INDEX` 已重生成（两篇归同一 id）
- [x] **Stage 6b**（2026-09-10 第二轮返工后重跑）机检总闸 `--node 10343:4`：`integrity` / `typography-icon` / `bilingual-spacing`（95 单元 0 findings）/ `connector` / `geometry-consistency` / `variant-axis` / `hash-n-semantic` / `jira-hyperlink` / `feedback-not-selfdrawn` / `source-link-integrity` **10 条 PASS**；`overlap` 2 条 = 两个 `Mark area`（设计意图）；`colors 336` / `library-origin 118` / `binding-fidelity 2593` / `library-binding 1794` / `default-white-bg 284` = **file-wide owner-deferred（§M49.1）**。
  - 🔴 **P11 已解**：上一轮记的 `rulesErrored: 1` 不是「未定位」，闸自己就打印了成因与修法 —— **离线缓存 `figma-data/mockup/0054ib….json` 过期** ⇒ `library-binding` 记 ERROR。跑 `pnpm sync:mockup 0054ib0nLmt27bC3QlGDl7` 后重跑，`rulesErrored: 0`，该闸真跑起来了。
  - ⚠️ `connector` 闸**自报降级**：orthogonal×7 / anchoring×7 / dot-shape×3 / color×4 没跑（REST 不暴露 `vectorPaths`），且只解析到 7 条（实际 11 条）⇒ **它的 PASS 不构成连线验过**，连线必须走 use_figma 自审（见 §1b-1 与 handoff §3）。
- [x] **Stage 7** 走查已跑完，两份报告：
  - **F1** [`docs/audits/2026-09-10-v4-1646-f1-walkthrough.md`](../audits/2026-09-10-v4-1646-f1-walkthrough.md) —— page type = Settings/Form · 三轴 + 两个固定层全 FIRED（§5.9 因非代码交付判 SKIPPED）· PRD 覆盖 6/6 · 命中 2 条 anti-pattern（「只查组件名不查渲染实况」+ meta-rules §3 第 7 条「声明了 ≠ 被消费」）· **2 high / 3 medium / 4 low**
  - **F2** [`docs/audits/2026-09-10-v4-1646-f2-persona-simulation.md`](../audits/2026-09-10-v4-1646-f2-persona-simulation.md) —— 3 personas（答题率 P1 5/6 · P2 3/5 · P3 4/5）· **独立于 F1 抓到 2 条新问题**
  - **走查中已自修 1 条**：C/C2/C3 的 `OK` 原为 `Status=Normal`（空表单可点）⇒ 与 PRD 验收 A3「为空不可提交」自相矛盾，已切 `Status=Disabled` 真变体并渲染亲验
  - **走查产出的 3 条待 owner 拍**：① D18 落位 24 vs 54（F2 补了 persona 层依据：导航标题是「远程支持」唯一的远程定位凭据 ⇒ 三 persona 一致指向 54）② 面板选项行 35/36 < 44px 最小点击区（提到 44/46 实测装得下：面板 71→90、底缘 242 < 内容区底 274）③ 失败文案在 WPA3-only 场景主动误导
- [ ] **Stage 8** Jira 回复（⛔ 等 owner 定稿；格式 = `UX Design updated.` + 短锚文本 Figma 链接 + @PM Trevor Yao + cc Edward Wu）+ **assignee 转 Edward Wu**（当前 assignee 是 Nancy Zeng；`design-process.md:208` 硬规则）

---

## 8. 命中的规则清单（§M48 起手 self-check）

**产品层**：M0 · M17 · **M17.1（已触发并落地，2026-09-10）** · M21.4 · M32（LCD 走 file-local 是正常落点，⛔ 别反向纠错）· M32.4 · M32.5 · M32.6 · M37.3 · M38 · M53 · M54（设备固定屏，单档即满足）· M-FONT · M-TXT-ICON-AUDIT（`▼▲` 可用，`▶` 无字形）· 字体规范（Verdana 不可写 ⇒ 出待改清单交 owner）
**交付层**：M23 · M23.0 · M23.6(A)(C)(D) · M23.7 · M23.8 · M23.8.1 · M23.10 · M23.11 · M23.12 · M23.14 · M23.18 · M23.18.1 · M23.19 · User Journey Map 卡
**颜色**：M-COLOR C1–C8（C4 注释 accent 与品牌色不混用 · C5 语义色优先 · C8 一信号一语义）
**结构**：M-INTEGRITY I1–I7（I2 每次收尾扫 section 重叠 · I6 create/move 前 probe 落点 · I7 改容器尺寸后复测）· M31 · M42 · M42.2 · M42.3 · M45 · M45.1 · M46 · M-LIFECYCLE 三时点 · Q15（SECTION 子节点坐标 section-relative）· Q22（SLOT）· Q29（库订阅判定）
**纪律**：M-DISCIPLINE.SOURCE / .SCOPE / .MEASURE / .SYNC / .VARIANT · M-GATE-FALSIFIABILITY · M48 · M49 · M52.1–M52.4

---

## 9. 回流候选 —— ✅ **owner 2026-09-11 拍定「七条全升」**（R1–R7 进 DS；R8 为本轮新发现，同族）

先过 DS `mockup-conventions.md` §M-DISCIPLINE.SOURCE 三问（① 换个产品还成立吗 ② 做法还是取值 ③ 别的 consumer 会被误导吗）：

| # | 候选规则（做法层） | 三问判定 | 实证 | 建议落点 |
|---|---|---|---|---|
| **R1** | **`clone()` 的落点不可假设** —— `node.clone()` 不保证与源节点同 parent；跨 SECTION 边界时可能落到 CANVAS 上。凡 clone 后要定位，必须**显式 `appendChild` 到目标容器再设坐标**，并复验 `node.parent.type` | ① 成立（任何 Figma 产品都会 clone）② 做法 ③ 会 —— 现有 Q15 只讲「SECTION 子节点坐标是 section-relative」，没讲「clone 出来的可能根本不是 SECTION 子节点」 | 本轮 E2：C2/C3 落到 PAGE 上，page 坐标 3020 被当成 section 坐标，两帧实际压在 D/E 上 | DS —— 并入 **Q15** 作 sub-clause |
| **R2** | **几何自检必须统一坐标系取数** —— 比较任意两个节点的 bbox 前，先确认它们**同 parent**；不同 parent 一律换算到同一参照系（`absoluteBoundingBox`）再比 | ① 成立 ② 做法（判据） ③ 会 | 本轮 E2：我的碰撞检查混用 page/section 两套坐标 ⇒ 真重叠被判成「无碰撞」，比不查更危险（给了假绿） | DS —— 并入 **§M-INTEGRITY I6/I7** |
| **R3** | **`overlap` 机检有 parent-scope 盲区** —— 它只比同一 SECTION / CANVAS 的**直接**子节点，跨 parent 的重叠结构上看不见。⇒ 收尾几何自检**不能只依赖该闸**，必须自己按 R2 全量比一遍 | ① 成立（闸是 DS 的） ② 做法（闸的适用边界） ③ 会 —— 闸的 PASS 会被读成「无重叠」 | 本轮 E2：`overlap` 报 2 条（都是 Mark area），对真重叠零命中 | DS —— 记进该闸的 **unverified/适用边界**说明，与 §M-GATE-FALSIFIABILITY 同源 |
| **R4** | **变量「绑错」与「未绑」是两类问题，机检只看得见后者** —— 颜色闸判的是「有没有绑变量」，绑了**错的**变量一律绿。⇒ instance 的语义色必须与 `getMainComponentAsync()` 上同名节点的 `boundVariables` **逐条比对**，不一致即为 finding | ① 成立 ② 做法（核查项类别） ③ 会 | 本轮 E1：error 提示文字绑 `UX/Blue/Default`，五闸全绿，只有渲染图看得出来 | DS —— 并入 **§M-COLOR** 作新 sub-clause |
| **R5** | **canonical 帧只有一个可见单元时，不构成「多单元排布」的先例** —— 照 canonical 建时要先数它有几个同类单元；只有一个，则「本单元与相邻单元怎么互动」这一面**在 canonical 里没有答案**，须显式立判据而不是外推 | ① 成立 ② 做法 ③ 会 | 本轮：canonical 选项面板帧 `5314:9520` 只有一行可见字段 ⇒ 「面板向上展开」不是范式而是「它恰好是最后一行」的结果。本单 `Security` 是**中间行**，向上会切上一行文字、向下才成立 —— 这个判据 canonical 给不出 | DS —— 并入 **§M17** 通则（与「照最近做过的页仿写」是同一族病灶的另一面）|
| **R6** | **「Change Log 注释每档都要」在 W3 档不成立** —— skill §6-JIRA.W 现文写「⑦ 是每档都要的，卡族替代不了它」。但该条的实证来源是 **W1 档**（无卡族，Change Log 是「改了哪里」的唯一载体）。**W3 档已有 PRD 卡 + UX 卡 + Journey 卡 + BEFORE/AFTER 分属两 Section + 流程连线**，delta 定位已充分 ⇒ ⑦ 的边际价值只剩圈选框，代价是恒产 overlap findings 要每轮解释归属。建议改为：**W1 必产 · W2 建议 · W3 免除（除非 owner 点名要）** | ① 成立（任何 consumer 的 W 档判定） ② 做法（交付件档位映射） ③ 会 —— 现文的「每档都要」会让每个 W3 单都刷一个冗余模块然后被 owner 要求删 | 本单 D20：owner 逐字质疑「已经有 PRD、UX 交付 和用户体验地图，为啥还需要增加 Change log 这个模块」⇒ 建完再删，双倍成本 + 画布留痕，与 §6-JIRA.W 自己开头警示的 V4-2402「建了再删」**同一个坑的反向发作**（那次是卡族过重，这次是注释冗余）| DS —— 改 `skills/tvu-design-mockup/SKILL.md` §6-JIRA.W 的 ⑦ 与档位表 |
| **R7** | **落位类取值要按「宿主顶部结构」分族，不按单个数字定** —— 同一 surface 上并存两种顶部结构（有导航标题 / 只有状态 header）时，一个数字必然在其中一族上出错。做法：先按顶部结构分族，再对每族推导同一个间距规则 | ① 成立（任何有多种页头形态的 surface） ② 做法（判据形状：分族 + 单一间距规则，而不是枚举数字） ③ 会 —— 「距帧顶 Npx」这种写法读起来是通则，实际只对一族成立 | 本单：原项目规则「距帧顶 8px」在首页族对（盖状态图标带），在设置页族错（盖导航标题）；D18 想用一个 24 覆盖两族，结果两族都不满足 | DS —— 判据形状进 §M17 / §M37.3 一族；**取值（8 / 54）留项目 repo** `lcd-message-strings.md` §2.5 |

### 9a. R8 —— ✅ **owner 2026-09-11 已拍板升 DS 规则**（DS commit `e6abd3ca`）

> **落地形态**：`mockup-conventions.md` §M47.2 新增 sub-clause〈稀疏属性（`hyperlink` / `textDecoration`）逐段重设**盖不住** —— 必须先全清〉，含代码块 + 判据「有个节点没出事不能反推安全」+ 怎么验（并进既有 §Acceptance 的逐段复核，**未自立 Acceptance 段**）。同步改了索引行触发时机 + `design-process.md` §参考物落地的实现纪律（那里正是「重建后再挂链接」的高危路径）。
> ⚠️ **DS 侧写入时被两个闸拦过，都是我的问题，均按闸头注释修正、未改任何自陈数字**：① `acceptance-gate-coverage` S2（我写的 `**Acceptance**：` 被认成新建 Acceptance 段 ⇒ unclassified 36>35）→ 要求留正文、不自立段；② `source-discipline` SRC-A（我把 Config-T 两个帧 id 写进了 DS 真源）→ 按 §M-DISCIPLINE.SOURCE 改成描述形态 + 指回本文件 §1b-4，**取值留项目侧**。

| # | 候选规则（做法层） | 三问判定 | 实证 | 建议落点 |
|---|---|---|---|---|
| **R8** | **`node.characters = …` 会让整串继承第 0 个字符的 `hyperlink` / `textDecoration`；逐段回贴「只加不减」⇒ 必须先 `setRangeHyperlink(0, len, null)` + `setRangeTextDecoration(0, len, 'NONE')` 全清，再逐处加** | ① 成立（任何 Figma 产品改多段样式文本都会遇到）② 做法 ③ 会 —— §M47.2 现文只讲「整段覆盖 fontName → 赋 characters → 逐段重设」，**没讲 hyperlink/decoration 这两个属性是「继承 + 只加不减」的组合**，照现文做会静默放大链接范围 | 本轮：改日期戳 `2026-09-10→11`（**等长**替换，理论上最安全的一种改法），UX 卡与 Journey 卡整条 meta 行变成超链接；PRD 卡同样操作没事，只因它第 0 字符 `P` 本来没链接 ⇒ **「哪个节点没出事」不能反推安全** | ✅ **已升** `mockup-conventions.md` §M47.2 sub-clause（`e6abd3ca`）|

### 9b. R2 / R4 的量法补注（2026-09-11 第三轮复验实测，⛔ 回流时要连这两句一起带上，否则规则会被照成假阳性）

- **补 R2**：统一坐标系只解决了「拿谁的数」，还要解决「拿什么形状的数」。**折线 connector 不能按 bbox 判重叠** —— 本 Section 用 naive bbox 两两比对得 **101 条重叠，每条都至少一端是 connector**（`connector/C3-to-connecting` 的 bbox 是 3100×590，覆盖它跨越的所有帧）。剔掉 connector 后帧 × 帧 = 0。⇒ R2 的落地形态必须与 §M-DISCIPLINE.MEASURE 的「折线逐线段」接线，否则规则本身会稳定产出假阳性。
- **补 R4**：「与 `getMainComponentAsync()` **同名**节点逐条比对」这个量法**在文本节点名跟随内容的组件上失效**。Message 的文本节点名就是文案本身（`Connected to Guest_Hidden — reconnect after reboot.`），主组件里不存在同名节点 ⇒ 按名 join 恒 `null`，三条语义色会被全报成 mismatch。⇒ R4 写进 DS 时判据要写成「按**子节点索引 / 结构位置**对齐后比 `boundVariables`，并以渲染 hex 作交叉验证」，⛔ 不能写「按同名节点比」。

**项目档取值**（不进 DS，留本仓）：C2 面板 240×71 @ (216,152) · 阶梯 VECTOR `432×117` 路径 · 三角 clone 源 `8878:21` · 五帧标题节点 id · 顶部提示落位 8 / 54 两档与 8 处先例实测表 —— 分别记在 §1b-1 与 `lcd-message-strings.md` §2.5。
