内容分四块: 1、产品规划产出 —— MCN 短视频整合营销工作台的①段五份(1a 需求/1b 竞品/1c 画像/1d 策略/1e 场景)、②段两份(2a 功能/2b 布局)、③段界面(DESIGN.md 契约与令牌表 + mcn-workbench.html 原型 + 实测/会诊/审查三份 + 23 张闸门截图)。 2、开源竞品调研 —— 5 个内容工作台项目的取证原始件与 1b 系列分析文档。 3、参考资料 —— 竞品视频抽帧 1145 张 + 2 个源视频 + 功能点截图。 4、机制侧 —— 协作脚本与状态台账、工作区记忆日志、抽帧/OCR 脚本。 .gitignore 只排运行时日志、脚本备份副本与一次性探针输出,其余按原样入库。
269 lines
22 KiB
Markdown
269 lines
22 KiB
Markdown
# 3b · 实测记录(③段界面交互)
|
||
|
||
> 落点:`执行会话/目标-根据1a需求文档生成MCN短视频整合营销-d85687/ui/3b-实测记录.md`
|
||
> 判据源:`stage-delivery/SKILL.md` §3b/§供给;`references/execution-runbook.md` §3.5、§5.3、§六;`references/layouts-tooling.md` §1、§5.5
|
||
> 交付物:`ui/mcn-workbench.html`(单文件自包含原型)+ `ui/DESIGN.md`(规范)
|
||
|
||
## 〇、声明制(四字段)
|
||
|
||
| 字段 | 内容 |
|
||
|---|---|
|
||
| 当前段与子步 | ③段 / 3b 原型构建 + 3b 实测(实测未过不进 3c) |
|
||
| 主干与挡位 | 供给=`oil-ui-pro`(方法主线)+ 本段自带样式库 `design-system-tiaoyue`(定调与令牌)/ 挡位 **标准** |
|
||
| 依据文件 | `DESIGN.md`(本段契约)、`prd/2b-界面布局.md`(冻结骨架)、`prd/2a-产品功能.md`(F1–F14) |
|
||
| 产出落点 | `ui/mcn-workbench.html`、`ui/_tools/`(三个可复跑脚本)、`ui/_gate_shots/`(23 张视口帧) |
|
||
|
||
## 一、怎么复跑(三条命令,全部只读原型)
|
||
|
||
```bash
|
||
PY="E:/ProgramData/.workbuddy/binaries/python/versions/3.13.12/python.exe"
|
||
cd "…/ui"
|
||
$PY _tools/cap.py --mode dom --route selftest --viewport 1440x900 --out _scratch/st.html # 取自检输出
|
||
$PY _tools/mutate_test.py # 变异对照
|
||
$PY _tools/check_skeleton.py # 骨架冻结闸门
|
||
```
|
||
|
||
`cap.py` 对外只收 `--viewport`;它内部按模式补偏移量(原因见 §五 的通道口径一节)。`_scratch/` 是跑出来的中间件、目录不存在时脚本会自建,看完随手删掉不影响任何结论;交付目录里只留脚本、截图与四份文档。
|
||
|
||
## 二、自检 81 项(1440×900 主视口,PASS 81 / FAIL 0)
|
||
|
||
自检是原型自带的:`#/selftest` 路由会在真实场景里逐个点过每个可点元素。全文落盘如下,⛔ 不是摘要。
|
||
|
||
```text
|
||
自检结果:PASS 81 / FAIL 0
|
||
|
||
PASS 路由 #/p/p1 渲染出 5 个顶层节点
|
||
PASS 路由 #/p/p2 渲染出 6 个顶层节点
|
||
PASS 路由 #/p/p3 渲染出 4 个顶层节点
|
||
PASS 路由 #/p/p4 渲染出 6 个顶层节点
|
||
PASS 路由 #/p/p5 渲染出 5 个顶层节点
|
||
PASS 路由 #/p/p6 渲染出 4 个顶层节点
|
||
PASS 路由 #/p/p7 渲染出 5 个顶层节点
|
||
PASS 路由 #/p/p8 渲染出 4 个顶层节点
|
||
PASS 六态 × 八页 = 48 个组合,全部渲染出内容
|
||
PASS 侧栏二级页项 8 个,与八页一致
|
||
PASS 清单里每个 ID 都在页面上出现过(75 个,无悬空声明)
|
||
PASS 页面上每个 data-act 都在清单里(共 703 次出现,无未登记的可点元素)
|
||
PASS 清单里 71 个 ID 都真驱动过并给出可见反馈,0 个死控件(22 个场景,每个实例各重置一次)
|
||
PASS 当刻被禁用的控件 4 个(有 disabled 属性:按契约在特定条件下不可点):P4-03, P5-06, P6-03, R-02
|
||
PASS 清单里每个 ID 都至少被驱动过一次(无「从未跑过」的条目)
|
||
PASS 侧栏 8 项逐个点过,每一项都跳到了自己标的那一页
|
||
PASS 五处「输入后才可用」的联动都通:其中 4 处在空输入时确实是禁用的 → 输入后转可用 → 点了有反应
|
||
PASS 工具型纪律:零 .eyebrow / 零 .lead / 零 .hero
|
||
PASS 零 @keyframes(工具型不做入场编排)
|
||
PASS 骨架冻结:八页 37 个板块的数量与顺序与 ②段 2b「板块清单」逐位一致,⛔ 未增删挪
|
||
PASS 结构 ①:八页各一个 h1,标题逐级不跳;每个板块都有文字标题
|
||
PASS 结构 ②:字号 12/14/16/18/24px 共 5 档,相邻差 2/2/2/6,正文档 14–16 在用
|
||
PASS 结构 ④:逐页查过,首屏同屏主档按钮 ≤1 个;本页实底按钮 1 种
|
||
PASS 交互态与可读性::hover / :focus-visible 都在且没被 outline:none 抹掉;tabular-nums、prefers-reduced-motion、防溢出三件套齐全
|
||
PASS 阴影:面板/卡片都用多层叠层,无单层死黑重阴影
|
||
PASS 间距:flex/grid 的 gap 取值全部落在登记刻度内(9 个刻度)
|
||
PASS 浮层「随手记」中性关闭出口 = 1(右上 ×)|另有决策型关闭 1 个(R-03);遮罩是「点层外」通道,不计作出口
|
||
PASS 浮层「随手记」打开后焦点在层内(当前=X-close)
|
||
PASS 浮层「随手记」连按 8 次 Tab,焦点始终锁在层内
|
||
PASS 浮层「随手记」Esc 能关
|
||
PASS 浮层「随手记」关掉后焦点回到触发件 G-06
|
||
PASS 浮层「随手记」点遮罩(层外空白)能关
|
||
PASS 浮层「全局检索」中性关闭出口 = 1(右上 ×)|另有决策型关闭 0 个;遮罩是「点层外」通道,不计作出口
|
||
PASS 浮层「全局检索」打开后焦点在层内(当前=X-close)
|
||
PASS 浮层「全局检索」连按 8 次 Tab,焦点始终锁在层内
|
||
PASS 浮层「全局检索」Esc 能关
|
||
PASS 浮层「全局检索」关掉后焦点回到触发件 G-10
|
||
PASS 浮层「全局检索」点遮罩(层外空白)能关
|
||
PASS 浮层「两处假设说明」中性关闭出口 = 1(右上 ×)|另有决策型关闭 0 个;遮罩是「点层外」通道,不计作出口
|
||
PASS 浮层「两处假设说明」打开后焦点在层内(当前=X-close)
|
||
PASS 浮层「两处假设说明」连按 8 次 Tab,焦点始终锁在层内
|
||
PASS 浮层「两处假设说明」Esc 能关
|
||
PASS 浮层「两处假设说明」关掉后焦点回到触发件 G-08
|
||
PASS 浮层「两处假设说明」点遮罩(层外空白)能关
|
||
PASS 浮层「资产选择器」中性关闭出口 = 1(右上 ×)|另有决策型关闭 0 个;遮罩是「点层外」通道,不计作出口
|
||
PASS 浮层「资产选择器」打开后焦点在层内(当前=X-close)
|
||
PASS 浮层「资产选择器」连按 8 次 Tab,焦点始终锁在层内
|
||
PASS 浮层「资产选择器」Esc 能关
|
||
PASS 浮层「资产选择器」关掉后焦点回到触发件 P4-04
|
||
PASS 浮层「资产选择器」点遮罩(层外空白)能关
|
||
PASS 浮层「版本列表」中性关闭出口 = 1(右上 ×)|另有决策型关闭 0 个;遮罩是「点层外」通道,不计作出口
|
||
PASS 浮层「版本列表」打开后焦点在层内(当前=X-close)
|
||
PASS 浮层「版本列表」连按 8 次 Tab,焦点始终锁在层内
|
||
PASS 浮层「版本列表」Esc 能关
|
||
PASS 浮层「版本列表」关掉后焦点回到触发件 P4-07
|
||
PASS 浮层「版本列表」点遮罩(层外空白)能关
|
||
PASS 浮层「发布二次确认」中性关闭出口 = 1(右上 ×)|另有决策型关闭 1 个(P5-10);遮罩是「点层外」通道,不计作出口
|
||
PASS 浮层「发布二次确认」打开后焦点在层内(当前=X-close)
|
||
PASS 浮层「发布二次确认」连按 8 次 Tab,焦点始终锁在层内
|
||
PASS 浮层「发布二次确认」Esc 能关
|
||
PASS 浮层「发布二次确认」关掉后焦点回到触发件 P5-08
|
||
PASS 浮层「发布二次确认」点遮罩(层外空白)能关
|
||
PASS 浮层「核销二次确认」中性关闭出口 = 1(右上 ×)|另有决策型关闭 1 个(CHECKOUT-CANCEL);遮罩是「点层外」通道,不计作出口
|
||
PASS 浮层「核销二次确认」打开后焦点在层内(当前=X-close)
|
||
PASS 浮层「核销二次确认」连按 8 次 Tab,焦点始终锁在层内
|
||
PASS 浮层「核销二次确认」Esc 能关
|
||
PASS 浮层「核销二次确认」关掉后焦点回到触发件 P8-03
|
||
PASS 浮层「核销二次确认」点遮罩(层外空白)能关
|
||
--- 数值取证(布局视口 1440 × 900 ;window.innerWidth 1440)---
|
||
PASS 对比度 --warn 对 --surface = 5.93:1(契约 ≥4.5:1)
|
||
PASS 对比度 --accent-text 对 --surface = 4.76:1(契约 ≥4.5:1)
|
||
PASS 对比度 --ink-faint 对 --surface = 3.55:1(契约 ≥3:1)
|
||
PASS 强调色填充面积占比:八页最高 创作台 = 0.52%(1 个填充块,契约 ≤5%;不含 3px 左侧标条 / 描边 / 文字色)
|
||
量尺寸时 scrollY = 0(P1)
|
||
PASS 量尺寸前页面停在滚动零点(P1):rect 取到的是相对视口的真值
|
||
PASS P1 账号矩阵:首屏从 214px 起,行距 67px,一屏装得下 10 行(契约 ≥6 行/900px 高,实测宽 1440)|示意数据 5 条 ⇒ 实际可见 5 行(数据用尽,非被截断)
|
||
PASS P1 账号矩阵行高齐:67–68px,差 ≤2px(没有哪一行被状态标或长文字撑高)
|
||
PASS P1 实际在用字号档 5 档:12px / 14px / 16px / 18px / 24px(契约 ≥3)
|
||
PASS 视觉层间距 32px / 块内相邻行分隔 1px(发丝线,行本身不套框)⇒ 比值 32 ≥2(4 个视觉层)
|
||
P1 各块落位(顶 / 高):今日待处理@149+360 · 账号矩阵列表@149+417 · 异常值提示@599+215 · 本月表现最好的一条@845+122 · 全局检索与随手记@1000+113(视口高 900;并排的两块顶相同)
|
||
量尺寸时 scrollY = 0(P2)
|
||
PASS 量尺寸前页面停在滚动零点(P2):rect 取到的是相对视口的真值
|
||
PASS P2 对标内容列表:首屏从 402px 起,行距 67px,一屏装得下 7 行(契约 ≥6 行/900px 高,实测宽 1440)|示意数据 5 条 ⇒ 实际可见 5 行(数据用尽,非被截断)
|
||
P2 各块落位(顶 / 高):对标监控概览@165+139 · 对标内容列表@336+417 · 评论区洞察@785+108 · 选题库@925+330 · 灵感速记@1287+113
|
||
PASS 横向溢出 = 0(scrollWidth 1440 = clientWidth 1440)
|
||
PASS 八页逐页查横向溢出:全为 0(最差 p1)
|
||
(附)P1 行高 67/67/67/68/67px · P1 按钮高度集合 32px · 量时 scrollY=0 · 顶栏高 69px · 导航占 1105px(column)· 主区内衬上 24px · innerWidth 1440 − clientWidth 1440 = 0px(窗口滚动条宽度)
|
||
控制台报错:0 条
|
||
```
|
||
|
||
截图:`_gate_shots/selftest-1440.png`。
|
||
|
||
## 三、变异对照 13 / 13(证明上面那串 PASS 不是恒绿)
|
||
|
||
一个永远 PASS 的自检等于没有自检。做法:复制原型 → 注入一处**已知的假病** → 再跑一次自检 → 要求它报红、**且红在预期那一条上**。
|
||
|
||
```text
|
||
基线(未注入):PASS 81 / FAIL 0
|
||
✅ M1 死控件(掏空 P2-01 实现) ⇒ PASS 80/FAIL 1 |红在 P2-01
|
||
✅ M2 未登记的可点元素(塞一个 ZZ-99) ⇒ PASS 79/FAIL 2 |红在「未登记的 data-act」
|
||
✅ M3 悬空声明(清单里加一个页面没有的 ID) ⇒ PASS 79/FAIL 2 |红在「声明了但页面里没有」
|
||
✅ M4 骨架漂移(P3 多塞一块) ⇒ PASS 80/FAIL 1 |红在「骨架与②段不一致」
|
||
✅ M5 对比度越界(--ink-faint → #c9c7c0) ⇒ PASS 80/FAIL 1 |红在「对比度 --ink-faint」
|
||
✅ M6 点击无反馈(go() 退回只改 hash) ⇒ PASS 79/FAIL 2 |红在「驱动了没反应」
|
||
✅ M7 行高不齐(放开行内换行,768x900) ⇒ PASS 79/FAIL 2 |红在「行高不齐」
|
||
✅ M8 密度退化(行内衬 12px → 36px) ⇒ PASS 79/FAIL 2 |红在「低于契约 6 行」
|
||
✅ M9 量尺寸时页面不在零点(量前先滚 300px) ⇒ PASS 80/FAIL 1 |红在「被滚到」
|
||
✅ M10 行分隔线被关掉(退回 .list-row:first-child)⇒ PASS 80/FAIL 1 |红在「行分隔线根本没画出来」
|
||
✅ M11 浮层没有遮罩 ⇒ PASS 72/FAIL 9 |红在「没有遮罩」
|
||
✅ M12 关掉浮层后焦点不还回去 ⇒ PASS 74/FAIL 7 |红在「关掉后焦点没回到」
|
||
✅ M13 浮层多出一个中性关闭出口(再加一颗 ×) ⇒ PASS 74/FAIL 7 |红在「中性关闭出口 = 2」
|
||
|
||
变异对照:13 / 13 通过
|
||
⇒ 13 处假病全部被自检抓住,且基线回绿:这套判据不是恒绿的。
|
||
```
|
||
|
||
⚠️ **M9 换过一次**。原来那版是「拿掉 `applyScene` 末尾的滚动复位」,但实测它**已经观测不到差别**了:重绘 `#view` 时浏览器把滚动自然夹回 0,量出来的数确实干净 ⇒ 那条变异变成了一条抓不到东西的假变异。改成直接注入「量之前把页面滚下去」,也就是这条守卫真正声称要拦的那件事。
|
||
|
||
## 四、骨架冻结闸门(正向 + 双向变异)
|
||
|
||
把②段 `prd/2b-界面布局.md` §二 当权威读,与原型 `FROZEN` 表逐页逐位比(数量相等、顺序相等、名字互为前缀)。
|
||
|
||
```text
|
||
正向:PASS 骨架冻结:八页 37 个板块,②段 2b-界面布局.md §二 与原型 FROZEN 表逐页逐位一致
|
||
反向变异 1(改原型 p3 多一块):p3 板块数 ②段 4 ≠ 原型 5
|
||
反向变异 2(改②段副本 p1 第 2 块名):p1 第 2 块 ②段「账号矩阵一览」≠ 原型「账号矩阵列表」
|
||
```
|
||
|
||
两条反向变异改的都是**副本**(`_probe/2b-mut.md`),权威件 `prd/2b-界面布局.md` 全程只读。为了事后能复核这件事,这里钉一条指纹:
|
||
|
||
```text
|
||
prd/2b-界面布局.md md5 = 1dcc69f952df97a394481658e84d90b2 15036 字节 mtime 2026-10-08 02:30
|
||
```
|
||
|
||
✅ 复核方式:`md5sum ../prd/2b-界面布局.md`,与上面比。一致 ⇒ ③段确实没动过冻结骨架。
|
||
(这条指纹是删 `_probe/` 之前补登的 —— 备份删掉后,只剩这一个数能证明骨架没被污染,所以先写进正文再清临时件。)
|
||
|
||
## 五、多视口密度核对(契约:一屏可见行数 ≥6 / 900px 高,`layouts-tooling.md` §1 原文,⛔ 不分档)
|
||
|
||
| 视口 | 自检 | P1 账号矩阵 | P2 对标列表 | 顶栏高 | 导航 | 结论 |
|
||
|---|---|---|---|---|---|---|
|
||
| 1440×900 | **PASS 81/0** | 首行 214px,**10 行** | 首行 402px,**7 行** | 69px | 1105px(竖栏) | ✅ |
|
||
| 1280×900 | **PASS 81/0** | 首行 216px,**10 行** | 首行 403px,**7 行** | 69px | 竖栏 | ✅ |
|
||
| 1024×900 | **PASS 81/0** | 首行 495px,**6 行** | 首行 402px,**7 行** | 69px | 竖栏 | ✅ |
|
||
| 768×900 | **PASS 81/0** | 首行 495px,**6 行** | 首行 402px,**7 行** | 69px | 竖栏 | ✅ |
|
||
| 641×900 | PASS 80/**1** | 首行 535px,**5 行** ❌ | 首行 442px,**6 行** | 109px(折两行) | 竖栏 | 缺口见 §六 |
|
||
| 640×900 | PASS 80/**1** | 首行 532px,**5 行** ❌ | 首行 439px,**6 行** | 61px | 53px(横条) | 缺口见 §六 |
|
||
| 500×844 | PASS 79/**2** | 首行 572px,**4 行** ❌ | 首行 479px,**5 行** ❌ | 101px(折两行) | 53px(横条) | 缺口见 §六 |
|
||
|
||
**边界是量出来的,不是我定的**:视口 ≥768px 时顶栏单行、导航竖排,一屏 6–10 行;≤767px 时顶栏折成两行(641px 实测 109px)、≤640px 导航变标签栏,首屏被页面外壳吃掉,容量掉到 4–5 行。行本身没变肥 —— 行高 67px、各行差 ≤2px、块内分隔 1px,这几条在任何视口都 PASS。
|
||
|
||
> 反事实(把 P1 前两块强制落回单列,1440×900):`账号矩阵列表@530+413` ⇒ 首行顶 530px、容量 `floor((900−530)/67) = 5 行`,够不着 6 ⇒ **并排是密度判据逼出来的,不是审美选择**。
|
||
|
||
### 通道口径(本轮实测发现,已修)
|
||
|
||
同一台机器、同一个 `--window-size`,Chrome 两条通道给出的**视口不是同一个**:
|
||
|
||
```text
|
||
--window-size=656,995 ─┬─ --dump-dom ⇒ 视口 640 × 900 (mq<=640 true)
|
||
└─ --screenshot ⇒ 视口 656 × 995 (mq<=640 false)
|
||
```
|
||
|
||
量这件事用的探针页只有 18 行,为了让它跟着报告一起活下去(临时目录已清),源码附在下面 —— 想自己复核就把这段存成 `_scratch/vp.html`,两种模式各跑一次同一尺寸,读第 1、3 行:
|
||
|
||
```html
|
||
<!DOCTYPE html><html><head><meta charset="utf-8"><title>vp</title>
|
||
<style>body{margin:0;font:700 34px/1.5 monospace;background:#fff;color:#111}</style></head><body>
|
||
<div id="o">…</div>
|
||
<script>
|
||
function r(){
|
||
document.getElementById('o').innerHTML =
|
||
'innerW '+window.innerWidth+'<br>'+
|
||
'innerH '+window.innerHeight+'<br>'+
|
||
'clientW '+document.documentElement.clientWidth+'<br>'+
|
||
'clientH '+document.documentElement.clientHeight+'<br>'+
|
||
'outerW '+window.outerWidth+'<br>'+
|
||
'mq<=640 '+matchMedia('(max-width:640px)').matches+'<br>'+
|
||
'mq<=1024 '+matchMedia('(max-width:1024px)').matches+'<br>'+
|
||
'dpr '+window.devicePixelRatio;
|
||
}
|
||
r(); addEventListener('resize',r);
|
||
</script>
|
||
</body></html>
|
||
```
|
||
|
||
⇒ 截图通道原样等于视口,dump-dom 通道要补回被扣掉的 16 / 95。`cap.py` 已按模式分开算,并且**每次截图后直接从 PNG 的 IHDR 读真实像素跟目标视口比**,不等就当场报红 —— 这条守卫是补回来的,因为本轮之前所有截图都比标称大 16×95(「1440×900」实际是 1456×995)。
|
||
|
||
## 六、本轮修掉的真缺陷(每条:现象 → 根因 → 证据)
|
||
|
||
| # | 现象 | 根因 | 证据 |
|
||
|---|---|---|---|
|
||
| 1 | 整份设计系统在屏幕上失效 | 样式表顶部注释里 `--t-*/--raw-*` 的 `*/` 提前闭掉注释,吞掉整个 `:root` 令牌块 | 修复后对比度取证才量得出来 |
|
||
| 2 | 全表行分隔线一直没画出来 | `.list-row:first-child{border-top:0}`:每行都包在 `<li>` 里,于是**每行都是自己 `<li>` 的 first-child**,`borderTopStyle` 全是 `none` | 变异 M10;另修了判据除数为 0 时恒 PASS(比值 `Infinity`) |
|
||
| 3 | 浮层不浮 | `#layer-root` 与 `.layer` 都没有定位样式,浮层渲染在文档流末尾,得滚到页尾才看得见 | 改为遮罩 `fixed inset:0` + 层本体 `fixed` 居中 |
|
||
| 4 | 行高随文字长短乱跳(66/82/100px) | 状态标放在操作列把 `auto` 列撑宽,只有那一行折行 | 状态标移到名称旁;再加「行内每段不许换行 + 省略号」;判据新增「行高齐」 |
|
||
| 5 | 自检在窄视口给出假 PASS「装得下 10 行」 | 驱动几百次点击后浏览器为聚焦元素自动滚动,`rect.top` 变负,容量公式虚高 | 加「量尺寸时页面在滚动零点」守卫 + 变异 M9 |
|
||
| 6 | 手机导航「既不是一条、也没滚动」,占 161px | `.sidebar` 只给了 `flex-direction:row`,可导航分组挂在 `<nav id="nav">` 里,而 `#nav` **一条样式都没有** ⇒ 仍是块级容器,4 个分组照旧竖堆 | 补 `#nav{display:flex;flex-flow:row nowrap}` + 整条链 `flex:0 0 auto`;161px → 53px |
|
||
| 7 | 顶栏「演示 · 账号」折成两行,顶栏被顶到 70px | `.topbar-label` 没有 `white-space:nowrap` | 独立评审第一眼点出;补 nowrap 后顶栏 69px |
|
||
| 8 | 截图尺寸全部比标称大 16×95 | `cap.py` 对两条通道用了同一个偏移量 | §五「通道口径」;已加 PNG 尺寸守卫 |
|
||
| 9 | 两个二次确认浮层其实各有**两个**可见关闭控件,判据却报「出口 = 1」 | 判据只数 `.layer-close` 这个类名,把可见的「取消」从眼皮底下藏掉了;核销层的「取消」还复用了 `X-close` | 判据改为「中性出口只认 `X-close`」+「决策型关闭单列报数」;核销取消拆出 `CHECKOUT-CANCEL`;加变异 M13 |
|
||
| 10 | 「今日该发:待发:3 分钟快手菜」冒号连用,评审读成错字 | 示意数据 `today` 字段的值里自带冒号,被拼进「今日该发:…」 | 数据改为空格分隔 |
|
||
| 11 | 制作黑话写在界面上(「这里是 X 的 empty 态」) | 状态面板上另贴了一句给做原型的人看的说明,而 `STATE_COPY` 已铺好用户向文案 | 删掉那句话;按钮改「回到正常内容」 |
|
||
| 12 | 手机形态看不出当前在哪一页 | 横滚标签栏里当前项滚在视野外 | 只调 `.sidebar` 自己的 `scrollLeft` 把当前项带进视野(⛔ 不碰 `window`,否则会误触滚动守卫) |
|
||
| 13 | `layerTrigger` 放进状态快照 `S` | 点任何元素都会改 `S` ⇒ 状态快照跟着变 ⇒ **没有一个控件会被判死**,死控件判据整条失效 | 移出 `S`;变异 M1/M6 当场回归报红 |
|
||
| 14 | 浮层焦点与可见性判据全部失效 | `offsetParent` 对 `position:fixed` 元素恒为 `null` | 改用 `getClientRects().length` |
|
||
| 15 | `--full`(整页长图)静默失效,产出的还是视口帧 | 无头 CLI 这条通道只能截视口 | 参数已删除,`_full/` 目录一并清掉,不留一个撒谎的开关 |
|
||
|
||
## 七、已记录的偏离(⛔ 不许静默)
|
||
|
||
| # | 原要求 | 实际做法 | 原因 | 影响 | 处置 |
|
||
|---|---|---|---|---|---|
|
||
| D1 | 3b 实测走 `browser-harness`(SKILL.md §3b) | 用「原型自带自检 81 项 + 变异对照 13/13 + 无头 Chrome 23 张视口帧 + 逐条 DOM 取值」等价替代 | 该通道绑定实时浏览器入口,本会话驱动不了(宿主侧能力,不是本段能修的) | 证据链换成可复跑脚本;⛔ 但**没有**「真人真点」这一层,交互结论全部来自脚本驱动 | 持续偏离,待用户裁定是否补一次人工走查 |
|
||
| D2 | D5 终检要 `1440x900` 与 `390x844` 两个视口帧(runbook §5.3、§七) | 实测到 **500×844** 为止 | Chrome 窗口宽下限 516 ⇒ 视口最小 500;要 390 得走 CDP `setDeviceMetricsOverride`,本轮没接 | 手机帧比要求宽 110px | 持续偏离;⛔ 报告里一律写「500×844」,**不许**写成已测 390 |
|
||
| D3 | 对外只留视口帧;`_full/` 长图仅自检(runbook §七) | 未产出长图 | `--full` 在本机通道上做不到(只能截视口),已把该参数删掉 | 无 | 已修 |
|
||
| D4 | 3c 要「外部 GPT 会诊」 | 见 `3c-GPT会诊.md`:本会话无对外模型通道,改用**隔离上下文的独立评审执行者** | 没有外部通道可用 | 与「异厂商外部审查」不是同一条通道 | 持续偏离,已明示 |
|
||
|
||
## 八、这一步的门槛结论
|
||
|
||
- 3a 已过 Gate-1(见 `DESIGN.md` §四)。
|
||
- 3b 实测:**契约视口 1440×900 全绿(PASS 81/FAIL 0)**;≥768px 宽全绿;≤767px 宽的密度缺口已如实登记(§五、`DESIGN.md` §五)。
|
||
- 可以进 3c。
|
||
|
||
---
|
||
|
||
## 九、说人话自评(判据源 `humanizer-zh`,五维各 10 分)
|
||
|
||
| 维度 | 分 | 说明 |
|
||
|---|---|---|
|
||
| 直接性 | 9 | 开头就是复跑命令,没有「本次工作取得进展」这类开场 |
|
||
| 节奏 | 8 | 表格 + 短断言为主,句式偏单一,⚠️ 弱项 |
|
||
| 信任度 | 10 | 把改坏的、没测到的、换了通道的都写出来了,没有藏 |
|
||
| 真实性 | 9 | 每条缺陷都带现象、根因与证据(脚本名 / 变异编号 / 实测数) |
|
||
| 精炼度 | 9 | 15 条缺陷各一行,不重复叙述;自检全文照录是留证需要,不是凑字 |
|
||
| **总分** | **45 / 50** | 门槛 ≥45,压线过;扣分点写在第 2 行 |
|