# 审计报告 Lane B — KAP 无限画布：前端交互与信息架构审计

- 审计对象：`/data/workspace/kais-aigc-platform/packages/infinite-canvas/src/`（183 个 ts/tsx，~2.7MB）；后端对照：`/data/workspace/kais-aigc-platform/src/routes/canvas/v2/` + `src/lib/canvasRelationalStore.ts`
- 审计方式：纯静态源码走查（只读）+ 线上服务 GET 探活（:10588 → 200）+ git 只读核对基线 commit 3544c3b4
- 审计日期：2026-09-19

---

## 1. 执行摘要

画布前端整体工程质量中上：选择器纪律干净（零整店订阅）、写路径乐观更新+外科回滚成熟、gateStore/qcVerdict 边界教科书级，3544c3b4 的 P1×4 直达改造确认全部真实生效。但存在四个事故级缺口：**ErrorBoundary 写好却从未接线（任何渲染错误=整页白屏）**、**后端不可达时静默加载示例假数据冒充真数据（仅 3 秒 toast）**、**万级节点无视口裁剪且每个 socket 事件触发全图重布局（11485 节点画布编排期不可用）**、**save-v2 无版本控制 last-write-wins 可静默丢数据**。另有「判定件跟镜走」半落地（播放器旁无判定件）、盲选页无 GT 参照板两处违反既定 UI 纪律。

### P0 清单

| # | 问题 | 服务对象 |
|---|------|---------|
| P0-1 | ErrorBoundary 存在但全应用零挂载，任一渲染错误整页白屏 | Kai / 平台健康 |
| P0-2 | 后端故障时静默渲染 fixture 假数据，无持久标识 | Kai / KMC / KGR（验收误判风险） |
| P0-3 | 11485 节点规模无 onlyRenderVisibleElements + socket tick 全量重布局 | KMC 监看 / 平台健康 |
| P0-4 | save-v2 六调用点无串行化/无版本锁，last-write-wins 丢数据；selectWinner 整图回滚吞 socket 更新 | KMC / 平台健康 |

---

## 2. 问题清单

### P0

**P0-1 ErrorBoundary 写好但从未接线**
- 现象：`components/ErrorBoundary.tsx` 是高质量 class 边界（getDerivedStateFromError :33、componentDidCatch :37、带重试 fallback :71-114），但全仓库无 `<ErrorBoundary` 挂载点。
- 证据：grep `<ErrorBoundary` 仅命中自身定义；`main.tsx:102-106` 直接 render `<FlowCanvas/>`；`FlowCanvas.tsx:1191-1214` 各视图分支（StoryboardTimeline/AssetManager/PipelineStateMachine 等）与 :1219 `<ReactFlow>` 均无包裹。
- 根因：组件与接线分属不同 phase，接线步骤漏掉。
- 影响：3091 行的 StoryboardTimeline 或任一 node renderer 抛错 → 整页白屏连顶栏都不剩。审片工具可用性事故级。
- 修复（S）：main.tsx:102 包 `<FlowCanvas/>` + FlowCanvas.tsx:1191-1214 各视图分支各挂一个。

**P0-2 后端不可达 → 静默换假数据，仅 3 秒 toast**
- 现象：初始加载失败时自动加载 decompose fixture 并以真数据形态渲染，唯一提示是 3 秒自动消失的 warning toast。
- 证据：`v3/fixtureSource.ts:99-112`（catch 任意错误 → loadFixtureGraph，fallbackUsed:true）；`canvasStore.ts:502-503`（仅 showToast）；`canvasStore.ts:279`（AUTO_DISMISS_MS=3000）；`canvasStore.ts:507`（fallback 路径照样 setLoadError(null)）；`FlowCanvas.tsx:1177-1187` 错误条唯一赋值点是 :550「该项目暂无数据」——只覆盖空项目，不覆盖网络故障。
- 根因：「fail-soft 不崩画布」契约被延伸为「假数据冒充真数据」，fallback 态未进任何持久 UI 状态。
- 影响：Kai/KGR 可能在不知情中对示例数据做审核判断；断网恢复后无自动重载真数据通道。
- 修复（S）：fallback 时点亮持久横幅（复用 loadError 错误条），canvasStore.ts:507 不无条件清 loadError。

**P0-3 万级节点画布无视口裁剪 + socket tick 触发全图重布局**
- 现象：ReactFlow 未开 `onlyRenderVisibleElements`（全 repo grep 零命中，`FlowCanvas.tsx:1245-1252` props 确认），11485 节点全部挂 DOM；编排期每个 `node:state` 事件 → `applySocketNodeState → applyGraphTransform`（canvasStore.ts:708-755）→ graph 换新引用 → `useLayout.ts:260-270` 全量重跑布局 + :380-404 全节点坐标重映射（每节点新对象引用，AssetCardNode 的 memo :901 全部失效）。`toLegacyVariantGroups/toLegacyBranches`（canvasStore.ts:454-456）每次调用新建数组（:284-306 纯 map 无 memo），十余个面板级组件（订阅 s.nodes/s.graph，如 StoryboardTimeline.tsx:2729/2533、VariantWall.tsx:58、BlindSelectionOverlay.tsx:96、FlowCanvas.tsx:159 等约 30 处）每 tick 无条件重渲。EventChipNode.tsx:55-61 每个芯片节点每 tick 做 O(links) 全链接扫描。
- 根因：架构按百级节点设计（useLayout.ts:11-14 自承「99 节点实测亚毫秒」），未为万级做裁剪/增量。
- 影响：KMC 跑管线时 Kai 无法同屏监看，画布基本不可用。
- 修复（S→L 阶梯）：开 `onlyRenderVisibleElements`（S，一票收益最大）；toLegacy* 加 WeakMap memo（S）；progress 瞬态不进 storeNodes / lanePlan 剔除 data.progress 依赖（M）；useLayout 增量脏子图重布（L，:11-14 已预留方案）。

**P0-4 save-v2 无版本/无串行化，last-write-wins 可丢数据**
- 现象：6 个 save-v2 调用点（`FlowCanvas.tsx:799, 841`、`CanvasContextMenu.tsx:122`、`canvasStore.ts:694, 974`、`useStaleRerun.ts:59`）各自取当时快照直接 POST，无队列/互斥/在途合并；后端 `save-v2.ts:25-93` 无 etag/version/冲突检测；`saveFullGraph`（canvasRelationalStore.ts:811-820）仍删除「DB 有而新图无」的行——旧快照晚到会删掉新快照刚加的节点。他端 graph:saved → 全量 reload（FlowCanvas.tsx:341-365）无本地脏检查；selectWinner 失败 `setGraph(prevGraph)` 整图回滚（canvasStore.ts:1024）会吞掉 await 期间到达的 socket 更新。
- 根因：保存路径从未做并发设计，乐观锁缺失。
- 影响：KMC 管线 save-v2 与画布手动保存交错时静默丢节点/回滚已确认状态——数据正确性事故。
- 修复（M）：前端保存串行化（save queue + 尾随合并）；后端加 meta.updatedAt 乐观锁冲突返 409（M-L）；selectWinner 回滚改外科式只回滚组内字段（S-M）。

### P1

**P1-1 播放器旁无判定件——「判定件跟镜走首屏」半落地（C2-F1）**
- 现象：播放中的镜，左播放器头栏只有 shotId+时长+✕，无 ✓/✕ 判定；判定钮只在 ShotRow 行内（StoryboardTimeline.tsx:1214-1221），且 selectShot 后无 scrollIntoView（:1410-1439 播放器头栏；全文仅 :2304-2321 有滚动同步）。>20 镜时正在播放的行大概率滚出视口，看完片段要捞行再判定。
- 根因：3544c3b4 P1-1 把判定件挂到「行」没挂到「播放中的镜」。
- 影响：Kai 审片主路径（播放→判定）在 >20 镜退化；KMC 人工门效率受损。
- 修复（S）：VideoPlayer header 挂现成 `ReviewActionButtons inline` + selectShot 时列表 scrollIntoView。

**P1-2 盲选页无 GT 参照板（C2-F2）**
- 现象：BlindSelectionOverlay 投票/揭晓两阶段均无 GT 参照，揭晓页只有来源标签+AI 分（:295-316）；grep `GT|参照|金标` 于 variants/ 目录零命中。`g15/GoldPanel.tsx` 有金标数据通道（scoreP09GoldGap）但未打通。
- 根因：防剧透纪律被扩大化到揭晓后。
- 影响：KGR 盲选终审无法对照 GT 校准，沦为纯口味投票。
- 修复（M）：揭晓页加 GT 参照条（当前 winner + 金标 gap 分）。

**P1-3 Socket 断连无感知 + 事件无序号/无去重（C5/C4-5）**
- 现象：useCanvasSocket.ts 无 connect_error/reconnect_attempt 监听（:141-293 只有 connect/disconnect/业务事件）；断连唯一信号是顶栏 11px `●/○`（FlowCanvas.tsx:1169-1171）；emit 在 socket null 时静默 no-op（:295-297）；重连补发仅当 `VITE_CANVAS_EVENT_REPLAY==='1'`（:124-125, 157-163），默认关 → 断线窗口靠 30s 轮询兜底全量 reload（FlowCanvas.tsx:918-946）；node:state 等事件无 eventId/序号（:172-200），乱序/重复直接覆盖 store 无守卫；graph:saved 触发的 reload 无防抖（KMC 连续 save 时前端反复整图刷新）。
- 影响：断网期间 Kai 继续看图做判断而数据悄悄过期；编排密集期偶发状态回跳。
- 修复（S-M）：加 connect_error/重连态提示（S）；事件带 eventId 客户端弃旧（M）；graph:saved reload 加 1-2s trailing 防抖（S）。

**P1-4 时间轴三态与资产库「自动选定」策略互相矛盾（C3-2）**
- 现象：时间轴宣称「用户手动选定前默认待选，不自动选 v1」（StoryboardTimeline.tsx:262），但 AssetLibrary 挂载即写库：无 primary 的组自动 PATCH isPrimaryView 选「最新非淘汰」（AssetLibrary.tsx:613-634，串行循环，失败静默 catch{}）。三态从 o_assets 拉取且 `assetsSynced` 只跑一次（:2639-2641），同会话内他端改动不刷新。
- 根因：两个 phase 各自落地，裁定未对齐；socket 无 asset-curation 事件。
- 影响：Kai 看到的「已选定 v3」可能只是打开过资产库的副作用而非人工决策；KMC 批跑触发资产库视图会大规模写 o_assets。
- 修复（S-M）：统一「是否允许自动选定」裁定（S）；切回 timeline 时强制 refetch 或走 socket 订阅（S-M）。

**P1-5 视频播放降级链缺口（C3-5）**
- 现象：无 videoUrl 且无 clipPath 的 shot 单击后静默无反馈，且 `activeVideo` 不清除——播放器继续播上一 shot 的视频，易被误判为该 shot 的成片（StoryboardTimeline.tsx:2738-2749 无 else 分支）；img onError 仅 `visibility='hidden'`（:964、:2490）留下空白盒子不回退文字占位。
- 影响：KMC 逆推项目 clipPath 缺失时排障困难；旧视频残留是误导性 UI。
- 修复（S）：selectShot 加 else 分支 setActiveVideo(null)+占位文案区分「该分镜暂无视频」；onError 回退文字占位。

**P1-6 变体墙选定 2 击 + 无 GT 参照；静帧 cover 裁 9:16（C2-F3/F4）**
- 现象：VariantWall 选定=点卡检视（:353）→底部「选定」（:481-492），卡面无常显钮；全墙无 GT 参照。ThumbOrPlaceholder 静帧 `objectFit:'cover'`（:509）而视频分支已是 contain（:368）——不一致，9:16 帧头尾被裁。
- 影响：审片墙是选镜主战场，每 take 多 1 击；竖屏帧判读面被裁。
- 修复（S~M）：卡面底部常显「★ 选定」（复用 P1-3 AssetThumb 模式）；静帧改 contain+深底；头栏加 GT chip。

**P1-7 资产中心竖帧缩略图 cover（C2-F5）**
- 现象：`assetManager.css:456` `.am-shot-frame__img` cover 装进 60×90 盒（:453-454），9:16（0.5625）源上下裁约 15%；:550、:703 同理。
- 修复（S）：改 contain（盒已接近竖比，视觉风险低）。⚠️ 裁切严重度取决于缩略源实际宽高比，修复前用真实 9:16 帧目验（待验证）。

### P2

**P2-1 canvasStore 1207 行单店混装约 10 域（C1-1/1.2）**
- 证据：域分布 接口 :41-225 / 实现 :427-1205（graph 生命周期、viewport、项目上下文、RF 派生缓存、分支 CRUD+REST 编排、deprecated variantGroups shim、加载位、UI 选中态、审核/删除/选优胜 API 编排、toast 系统、编排进度/视图模式/导航回调/Iteration 引擎）；store 直接 import services/canvasApi（:15,19）与 v3/serialize（:20），越界为应用服务层；setGraph 一次重写 7 域字段（:449-466）。
- 好的面：选择器纪律好——零整店订阅、零新对象字面量选择器；gateStore/qcVerdict 边界干净；无循环 import。
- 影响：改动定位成本高，双真相 shim（variantGroups :102-106、branches :455-456）是过渡债。
- 修复（L）：按域拆 slice（graph/UI/toast/审核编排），短期先做 P0-3 的 memo 止损。

**P2-2 variantOps 半死代码 + 空 import**
- 证据：生产只消费 `frameSlotOfGroup/nextReviewGroup/prevReviewGroup`（VariantWall.tsx:25、BlindSelectionOverlay.tsx:20、pipeline/NodeDetailPanel.tsx:15）；:13-244 大半无引用；`canvasStore.ts:21-22` 是空 `import { } from './variantOps'`。
- 修复（S）：删空 import 与死函数。

**P2-3 meta.viewport/pipelineId round-trip 静默有损（C4-1）**
- 证据：前端写（serialize.ts:377-387）且读（adapter.ts:639,642-644），后端 canvas_graph_meta 表只有 created_at/updated_at/last_event_id（canvasRelationalStore.ts:723-735、1016-1028、1036-1073），zod 校验过即丢。
- 影响：低-中。localStorage 兜底故用户无感，但 P17「viewport 是数据」在服务端路径是假的；pipelineId 血缘断裂。
- 修复（M）：meta 表加两列透传，或前端停止写入并标注。

**P2-4 分支 id 默认值分裂 `'br_main'` vs `'main'`（C4-2）**
- 证据：前端 adapter.ts:193/312 默认 `'br_main'`；后端统一 `"main"`（canvasRelationalStore.ts:127,216,341,832,897）且 save 时注入 main（:797-806）。缺 branchId 节点经前端再 save 会把 br_main 落库 → 双主线。
- 修复（S）：前端默认值改 'main' 或 adapter 归一。

**P2-5 load-v2 增量分支丢字段（C4-3）**
- 证据：`load-v2.ts:66-91` 本地 rowToNode（:121-133）丢 reviewStatus/aiScore/isWinner/rejectReason/variantGroupId/variantOf/suggestion；响应形状与全量不同构（无 meta/branches/variantGroups，:86-90）。当前前端不传 since（canvasApi.ts:361-369），是死契约，KMC 一旦使用即丢审核态。
- 修复（S）：复用 listNodes 行映射或删除 since 分支。

**P2-6 时间轴零策展 + 僵尸注释（C3-1/C3-3、C2-F7）**
- 现象：时间轴本体零策展交互，未选定帧占位「到资产管理中心选定」为纯文本不可点（StoryboardTimeline.tsx:1171-1187）；:2564-2568 与 :252-264 注释详述已不存在的点选/PATCH 交互，deriveInitialCuration 函数体只剩 `return 'candidate'`（:261-264）——僵尸文档误导后续维护与 KGR 知识抽取。
- 修复（S/M）：清僵尸注释（S）；占位做成 deeplink 直开变体墙锚定该组，复用 reviewAnchor 模式（M）。

**P2-7 G16 听审工作台行级无判定件（C2-F6）**
- 证据：G16VoiceWorkbench.tsx:224-258 行无动作钮，:322-349 仅底部批量豁免，无单行通过/驳回/重录。
- 修复（M）：行尾挂 ✓/✕ 小钮复用 ReviewActionButtons inline。

**P2-8 时间轴渲染放大：shots 渲染 4 遍 + memo 被内联 props 击穿（C3-4 局部）**
- 证据：主列表 shots.map（:2869-2883）+ 右侧竖幅轴 3 处 shots.map（:2437/2446/2457，每矩形带 img :2482-2491）+ TrackLane spans.map；ShotRow/FrameBox 未 memo（:925/:1002）且父传内联 onClick（:2875-2878）；DualTierStrip memo 被非 useCallback 的 selectShot（:2732）击穿；frameCuration 对象传每行（:2881）；行高 querySelectorAll 全量测量（:2807-2819）；savedGraph 无帧变体时额外全量调一次 /canvas/convert（:2583-2617）。>100 shot 明显掉帧；无虚拟滚动（react-window/virtualizer grep 零命中）。
- 修复（S→M-L 阶梯）：回调 useCallback 化+ShotRow memo+frameCuration 按行 selector 化（S-M）；行虚拟化（M-L）。

**P2-9 装饰性 cover 残留 / useLod 注释数值过期**
- 证据：DualTierStrip.tsx:273/316、StoryboardTimeline.tsx:2490、AssetCardNode.tsx:887、SceneGallery.tsx:57（均非判读面，可不动）；useLod.ts:35-38 注释阈值（0.38/0.32/0.83/0.77）与常量 LOD_L0_MAX=0.22/LOD_L1_MAX=0.6（:13-14）不符——文档 bug。
- 修复（S）。

---

## 3. 「首页直达」纪律合规表（全高频动作 × 合规状态）

| 高频动作 | 入口/击数 | 证据 | 状态 |
|---|---|---|---|
| 打开画布→选项目 | 顶栏 ProjectSelector 直选 | FlowCanvas.tsx 顶栏 | ✅ |
| 进时间轴 | 顶栏视图切换 1 击 | FlowCanvas.tsx:1115 | ✅ |
| 播放片段 | 单击 ShotRow 即播（左栏常驻播放器） | StoryboardTimeline.tsx | ✅ |
| 审核判定（列表行） | 行内 1 击（3544c3b4 P1-1） | StoryboardTimeline.tsx:1214-1221 | ✅ |
| 审核判定（播放中的镜） | 需找回列表行，>20 镜断链 | StoryboardTimeline.tsx:1410-1439 | ❌ P1-1 |
| 审核判定（画布卡） | 卡角 1 击常显（P2-1 已落地） | NodeBadges.tsx:153-162、ReviewActionButtons.tsx:172 | ✅ |
| 变体选定（pipeline 详情） | 缩略图 ★ 1 击（P1-3） | pipeline/NodeDetailPanel.tsx:338-365 | ✅ |
| 变体选定（变体墙） | 2 击 + 无 GT 参照 | VariantWall.tsx:353,481-492 | ⚠️ P1-6 |
| 变体选定（时间轴帧） | 多跳资产中心 | StoryboardTimeline.tsx:1171-1187、AssetLibrary.tsx:902-913 | ❌ P2-6 |
| 资产选定（资产库） | 卡面 ★ 常显 1 击 | assetManager.css:343-346 | ✅ |
| 成片终审 | portal EpisodeFinalReview（P1-4，画布仓外） | portal/src/pages/EpisodeFinalReview.tsx | ✅ |
| 盲选/金标入口 | 工具栏 1 击直达 | FlowCanvas.tsx:1355-1371 | ✅（但无 GT 板 ⚠️ P1-2） |
| Gate 放行 | chip/工具栏直达 + sticky 动作条 | FlowCanvas.tsx:1309-1314、GateTodoChip.tsx:41-66、GateCenterBlock.tsx:236 | ✅ |
| G15 分诊 | 工具栏直达 + sticky 批量条 | FlowCanvas.tsx:1303-1308、G15TriagePanel.tsx:157 | ✅ |
| G16 听审判定 | 仅批量豁免，无行级判定 | G16VoiceWorkbench.tsx:224-258,322-349 | ❌ P2-7 |
| 9:16 contain | 主图/播放器/盲选 ✅；变体墙静帧/资产中心帧 ❌ | StoryboardTimeline.tsx:1465、NodeDetailPanel.tsx:419、BlindSelectionOverlay.tsx:396/403 ✅；VariantWall.tsx:509、assetManager.css:456 ❌ | ⚠️ P1-6/P1-7 |
| 三栏布局（>20 镜） | 左播放器/中列表/右竖幅轴，非纵向长页 | StoryboardTimeline.tsx:2977-2999 | ✅（右栏非紧凑选镜列，配合 P1-1 scrollIntoView 补足） |
| GT 参照板显性展示 | 盲选/变体墙均无 | BlindSelectionOverlay.tsx 全文、VariantWall.tsx 全文 | ❌ P1-2/P1-6 |

**已确认真实生效的基线修复**：3544c3b4（P1×4）与 ee87383c（P2×2）逐项核对均在代码中存在且接线正确。

---

## 4. 改进建议（按服务对象分组）

### Kai 交互效率
1. **P1-1 播放器头栏挂行内判定件 + selectShot scrollIntoView**（S）——主路径「播放→判定」跟镜闭环，一票收益最大。
2. **P1-5 无视频 shot 显式空态 + 清 activeVideo**（S）——消除误导性旧视频残留。
3. **P1-6/P1-7 判读面 9:16 全部 contain**（S×2）。
4. **P2-6 时间轴「未选定」占位改 deeplink 直开变体墙**（M）。

### KMC 验收效率
5. **P0-3 开 onlyRenderVisibleElements + toLegacy* memo**（S）——编排期同屏监看可用的最小止损。
6. **P0-4 保存串行化 + selectWinner 外科回滚**（M）——管线 save 与人工操作不再互相丢数据。
7. **P1-3 graph:saved reload 防抖 + 事件序号**（S-M）——消除编排期状态回跳。

### KGR 终审效率
8. **P1-2 盲选揭晓页 GT 参照条**（M）——金标轨资产进入决策点。
9. **P1-6 变体墙头栏 GT chip + 卡面常显选定**（S~M）。
10. **P1-4 统一「自动选定」裁定**（S）——「已选定」必须等于人工决策，终审语义才可信。

### 平台健康
11. **P0-1 ErrorBoundary 接线**（S，组件现成）。
12. **P0-2 fixture fallback 持久横幅**（S）。
13. **P2-2 清 variantOps 死代码/空 import；P2-9 清 useLod 过期注释**（S）。
14. **P2-4 分支 id 归一 'main'；P2-5 增量契约补字段或删除**（S）。
15. **P2-1 canvasStore 按域拆 slice**（L，待 P0 止损后规划）。

---

## 5. 验证方式（operator 独立复核路径）

本审计全程只读，所有结论可按下述路径独立复核：

1. **行号复核**：报告内每条 `文件:行号` 均可直接 `sed -n 'X,Yp' <file>` 核对（行号已逐行目验，非 grep 推断）。
2. **ErrorBoundary 未接线**：`grep -rn '<ErrorBoundary' /data/workspace/kais-aigc-platform/packages/infinite-canvas/src/` → 仅命中 ErrorBoundary.tsx 自身。
3. **fixture fallback**：读 `v3/fixtureSource.ts:99-112` + `canvasStore.ts:502-507,279`；动态验证 = 断后端后 `curl -s http://localhost:10588/` 仍 200，无头浏览器打开页面 3 秒后无持久故障标识（本审计仅静态+GET 探活确认 200，**动态白屏/假数据呈现效果待验证**）。
4. **P1×4 基线**：`git -C /data/workspace/kais-aigc-platform show 3544c3b4 --stat` + 对照本报告 §3 表内行号。
5. **性能结论**：`grep -rn 'onlyRenderVisibleElements\|react-window\|react-virtual\|virtualizer' src/` → 零命中；useLayout.ts:260-270 memo 键与 canvasStore.ts:708-755 调用链可静态确认；**11485 节点实测帧率未动态测量，标「待验证」**（架构性结论由调用链推导，置信度高）。
6. **后端契约**：对照 `src/routes/canvas/v2/load-v2.ts:66-91`、`src/lib/canvasRelationalStore.ts:723-735,1016-1028`、`src/types/flowgraph-v2-schema.ts:92-100`。
7. **局限声明**：未运行动态页面观察/Playwright（环境可用性未确认，静态证据已充分）；9:16 裁切严重度依赖真实素材宽高比（待验证）；KMC 后端调用源在 `/data/workspace/kais-hermes-skills`（本仓外，未审计）。

---

## 6. 摘要（≤300 字）

画布前端底子好于预期：选择器零滥用、写路径乐观+回滚成熟、P1×4 直达改造全部真实生效，三栏布局与主图 contain 纪律基本合规。但四个 P0 必须优先处置：ErrorBoundary 写好未接线（白屏风险）、后端故障静默换假数据（验收误判风险）、万级节点无裁剪+socket tick 全图重布局（KMC 监看不可用）、save-v2 无版本锁 last-write-wins（数据丢失风险）。交互纪律残余违规集中在三处：判定件挂在「行」而非「播放中的镜」（>20 镜断链）、盲选/变体墙无 GT 参照板（KGR 终审无校准锚）、部分 9:16 判读面仍用 cover。修复排布上，P0-1/P0-2/P1-1/9:16 contain 均为 S 成本，建议先行；P0-3 用 onlyRenderVisibleElements 一票止损后再规划 useLayout 增量重布（L）与 canvasStore 拆 slice（L）。所有结论附文件:行号可独立复核，动态项已标「待验证」。
