# §M33 `SCREEN · ` 改造 —— 执行期裁决留痕（R1–R14）

> 这些裁决产生于 2026-09-15 那次 subagent 驱动的实施（计划 = [`docs/superpowers/plans/2026-09-15-m33-screen-prefix.md`](../../../superpowers/plans/2026-09-15-m33-screen-prefix.md)）。
> **它们原本只存在于 gitignored 的 SDD 台账里，合并后会随工作区一起消失** —— 故摘录进仓。
>
> 形态统一是「**裁了什么 — 为什么 — 若裁错代价是什么**」。⛔ 这不是规则真源：
> 判据口径的真源是 `docs/internal/mockup-conventions.md` §M33，出场条件的真源是 `scripts/mockup-rules/index.mjs` 的 `QUARANTINE`。
> 本文件只回答「当时为什么那样决定」。

## 🔴 先读这条：R9 的事实前提当初是错的

`R9` 写的是「保留代码的宽松匹配、改文档去对齐」，依据是「`PRODUCT_FRAME_RE` 比文档更宽（`SCREEN·X` 也过）」。
**那个依据是假的** —— 最终评审现取实测：旧正则 `/^SCREEN\s*·\s/` 的中点**后**要求至少一个空白，
`SCREEN·X` / `SCREEN ·X` 实测都是 `false`，而 §M33 却写着「也过」⇒ 照文档写名字的人会**静默不判**。

⇒ 最终修复走的是**反方向的做法**（改正则去兑现文档，`\s` → `\s*`），但**保住了 R9 的原则**：
朝「多判」方向失败是安全方向，收紧反而制造新的静默不判。

⚠️ 教训（值得单独记）：**一条裁决可以原则对、事实错。** R9 从写下到被推翻只隔了几个任务，
期间没有任何东西会发现它 —— 发现它的是最终评审去**实跑了那五个样本**，⛔ 不是读代码推断。

---

## Ruling R1: Task 1 Step 1 里 `expect(r.unmarkedSkipped).toBe(2)` 改为 `toBe(3)` — 因为 Step 3 给的实现对**所有**未标记 FRAME 计数，而该测试树的 root `0:1` 自己也是 FRAME（root + 0:2 + 0:4 = 3） — 若裁错，实现者第一次跑测试即撞上，代价 = 一轮修正，⛔ 不会漏进产物。

## Ruling R2: Task 1 Step 1 的替换范围**扩大**到同时重写既有 `describe('findLanguageIsolationViolations — 造故障（每臂单独红/绿）')` 块（`tests/mockup-language-isolation.test.ts:58-139`，8 个 `it`） — 因为那 8 项全部假设旧语义（product 是兜底档），Task 1 反转默认档后会整块红，而计划原文只交代了替换 `classifyRegion` 那一块 ⇒ 实现者会撞上一堆"计划没提过"的红。重写须**保留**旧块四项意图（P1 单独红 · P2 单独红 · P1/P2 不重复计 · `--allow-node` 如实计数），并把已被反转的两项（「annotation 区中文不报」「reference 区中文不报」）改写为「**未标记区**的中文不报」+「**product 子树内** annotation 命名仍判」 — 若裁错，最坏是丢掉一条本该保留的回归覆盖，final review 会看到整块 diff。

---
## Ruling R3: 直接修 `docs/internal/_spikes/f149-evidence/{selfcheck,stage1}.mjs` 改走 `requireFigmaToken()` — 因为 `audit:figma-env-single-source` 的内容面 S6 在 **master 上就是红的**（我自己 `88d8f7d9` 引入），该闸挂 L4 pre-commit + L5 gate-chain ⇒ 挡发版，属「已推出去的回归」而非计划内任务 — 若裁错，最坏是多了两行本可不加的 import；⛔ 不修的代价是 master 持续红。commit `cd14e2dd`，现取复核 `EXIT=0 ✅ PASS`。
  ⚠️ 亲验纠正了 implementer 的归类：它报「2 个失败都与本改动无关」。实测 `demo-renderer-react` 在**主工作树通过 14/14**、只在 worktree 红 ⇒ 是 worktree 环境产物（`@tvu/wc` workspace 包解析不到），⛔ 不是 pre-existing 代码红；而 `figma-env-single-source` 是**真红且在 master 上**。两者性质完全不同，只看它的文字总结会漏掉后者。
  顺带：`.superpowers/` 补进 `.gitignore:89`（原本未忽略，会被误提交）。
## Ruling R4: 把评审的 Minor「`PRODUCT_FRAME_RE` 导入却没用，应加 `flags === ''` 断言」**提进修复轮**，⛔ 不按常规延后 — 因为「⛔ 不加 `/i`」是 binding Global Constraint，目前只能靠两个样本用例**间接**推断，而 flags 断言是它的直接钉子 — 若裁错，代价仅是多一条极廉价的断言。

## Ruling R5: 计划 Task 3 原写「核查项从 4 变 5 ⇒ `[4]`→`[5]`」是错的，已订正计划 —— 现取 `audit-acceptance-gate-coverage.mjs:318-321`
的 `countCheckItems()` 逐字是「数正文里 `·` 的个数 + 1」，而新 Acceptance 正文里的标记字面量 `SCREEN · ` **自带中点**
（第 1 条 2 个、第 5 条 1 个）⇒ 预计 `items` 会变成 **8** 而不是 5。现值实测 `#M33` → `state gated · items 4`。
## Ruling R6: `SCREEN · ` 前缀与既有 `BEFORE ·` / `AFTER ·` 命名冲突 —— 裁定**前缀优先、`BEFORE`/`AFTER` 降为其后描述**（`SCREEN · BEFORE — Config-T Network`）— 理由：标记是给机器读的入口、必须最前且唯一，`BEFORE`/`AFTER` 是给人读的语义、位置可让 — 若裁错，代价是活树里已有的 `BEFORE · …(baseline)` 设备帧改名时要多写一段，⛔ 但不影响判据正确性。

## Ruling R7: 「只对新交付生效」的分界 —— 裁定**绑到 §M-LIFECYCLE 第②时点的触碰节点**（本轮新建或重画的设备屏幕帧），⛔ 不用日期划线 — 理由：闸本来就按 `--node <触碰节点>` 跑，这样规则口径与执行口径同源、⛔ 不引入第二把尺 — 若裁错，最坏是口径偏宽/偏窄一点，可在真实交付里调。

## Ruling R8: 「不应含中文」与「设备语言**通常**= EN」互斥 —— 裁定**如实写明 P1 预设 device locale = EN**；目标设备 locale 本身是中文的帧**不在射程内**，走 `--allow-node` + handoff 写明 locale — 理由：TVU 终端实际就是 EN，把前提写出来比让闸假装通用更诚实 — 若裁错，代价是将来真出中文 locale 设备时要重新拍一次射程。

## Ruling R9: 文档写逐字 `SCREEN · ` 而 `PRODUCT_FRAME_RE = /^SCREEN\s*·\s/` 更宽（`SCREEN·X` 也过）—— 裁定**保留代码的宽松匹配、改文档去对齐**（补「匹配器容忍中点前后空白，但书写规范仍是 `SCREEN · `」）— 理由：宽松匹配朝「多判」方向失败，是安全方向；收紧反而会制造新的静默不判 — 若裁错，代价是书写不规范的帧名也被判，⛔ 那不是漏判。

## Ruling R10: 评审的 Minor 7（`---` 前缺空行 ⇒ CommonMark 把 6 行渲染成 setext H2 大标题）**提进修复轮**，⛔ 不延后 — 理由：那是**渲染 bug**、不是排版偏好，会让规则真源在网页上整段变形 — 代价：一个空行。
  同批提进修复轮的还有 M8（指向错了章节）· M9（违例码没写进规则）· M11（部分标记时同样报绿，fail-open 段只说了 0 个标记的情形）。
## Ruling R11: Task 4 与 Task 5 **合并为一次 dispatch** —— 两者都是小体量文本改动（`mockup-rules/index.mjs` 的 QUARANTINE 注释文字 · `SKILL.md` 的协议条目）、文件不重叠、都不带测试周期
— 依据 skill 的「Batch small same-shape work」；⛔ 并行派两个 implementer 会在同一分支上撞 commit — 若裁错，代价是两者的 review 面混在一起、需要分别指认，⛔ 不影响正确性。
## Ruling R12: 该冲突的根因是 `BEFORE ·` 这个说法同时覆盖两类东西，裁定**用取证实测的真实命名去消歧**，⛔ 不是删掉那一行 —
  取证读数：`BEFORE · Config-T Modem settings (baseline · …)` 1280×1438 = **设备屏幕帧**（该标）；
  `_before-label` 427×44 · `_before-label · modem settings` 487×44 · `_chip-before` / `_chip-after` = **细长标签**（不标）。
## Ruling R13: 计划 Task 6 Step 4 的「基线 3384 passed / 14 skipped」是 2026-09-10 旧值，本分支实测 ~3560 / 18 ⇒ 已订正计划（commit 8671c078）
— 并如实登记 `tests/demo-renderer-react.test.ts` 在**本工作树**必红（`@tvu/wc` workspace 包经软链 node_modules 解析不到），
而同一份测试在**主工作树现取 14/14 通过** ⇒ 判为环境产物、⛔ 不是回归、⛔ 不去修
## Ruling R14: 复核提出的残留缺口「放宽正则后『零撞车』未重测」—— 控制者**就地重测而非延后**：
  同一 7427 帧分母上，旧/新两式**都命中 0**；阴性对照 70 个帧名含 `screen`（任意大小写）、0 个含大写 `SCREEN`
  ⇒ 该 0 是真的没撞、⛔ 不是探针坏了 — 若裁错，代价是误判了撞车面；⛔ 但已有阴性对照排除。
