把项目从「手写 dist/」改成「wallpapers/ 是唯一真相来源,dist/ 由 pnpm build 生成」,
并补上配套的类型、门禁与抓取器。一次提交落地整条管线,因为拆开会留下不能构建的中间态。
- src/:运行时与模拟器源码(TS,strict),编译到 build/ 再拷进各分发
- tools/:build / dev / check-{syntax,paths,dist},以及抓取器与回归门禁 tools/checks/
(.scratch/ 下那批一次性脚本移入 tools/checks/ 并入库为长期门禁)
- wallpapers/:七档壁纸的源数据 + README.md(id/音频/预设的完整规范)
- docs/adr/0005-0008:构建管线与分发拓扑、模拟器契约、自包含 sim、每骨架资源布局
- .gitignore:排除 .scratch/ 的参考资料副本(上游 spine 整仓克隆 ~1.2 GB、
抓取侦查数据 ~680 MB)与调试转储;这些是本地调查材料,补偿会让仓库无法克隆
- 归一化 .gitignore/CONTEXT.md 行尾(工作区 CRLF、索引 LF 造成的整文件假 diff)
同时修掉三档卡住构建的未完工壁纸:
- kv45 的 meta.json 里 id 还是抓取期场景名 scene_main,经 downloader promote 正名为 kv45
- shajin / zhigengniao_juheye 的 meta.json 误用了骨架描述文件(name/spine/animations/pages)、
且都缺 preset.template.json;现按规范重建:骨架沉到 spines/<名>/(spine-ts 按 atlas 所在
目录解析贴图页)、补上元数据与单骨架预设,并清掉 zhigengniao 骨架里指向作者机的绝对路径
- 顺带 promote 已在 sources.yml 里的 kv46(月升之前,与兽共舞)
pnpm check 五道门全绿:10 个分发 / 7 档壁纸 / 141 处引用自包含。
1.5 KiB
1.5 KiB
07 — 视觉等价验收:把"画面没变"变成可执行的断言
Status: resolved Type: task
问题
verify-sim-page.mts 只证明"自包含包能跑",不证明"画面没变"。内联、模块合成、URL 重写这些改动都可能悄悄改掉渲染结果。
答案
tools/checks/verify-visual-equivalence.mts:当前 dist 的截图与重构前的存档截图(tools/shots/baseline-pre-refactor/,6 组)逐像素比对,判据 mean|diff| = 0 且 max|diff| = 0。结果:6 组全部逐像素相同。
配套方法:node tools/capture.mjs <tag> --base <url> 抓图,node tools/diff.mjs a b 比对。基线帧必须靠 --base 指向正确的分发根——指向调试服首页会抓到一张空白页(45 KB vs 2165 KB),差异看起来像"整体回归",实际只是抓错了页面。
一个误读
tools/capture.mjs 打印的 spine 层贡献: psnr=18.9 … 是同一轮里 ref 帧 vs 主帧的差("spine 层占了多少像素"),不是与基线的比对。我把它读成了后者,一度以为 spine 层与重构前不一致,白查了半天。
真正的判定只有 verify-visual-equivalence.mts。查证过程留下了两个有用的结论:
- 捕获是确定性的:同一份代码两次捕获逐像素相同(
?__freeze=1把trackTime归零并每帧强制,drawCalls=1437、trackTime=0)。 - 背景层(ref 帧)逐像素相同,所以差异(如果有)只可能来自 spine 层。