fix(pack): 编码取整与参考实现对齐 + 产物不再夹带测试夹具(v0.2.4)

两个缺陷,都由上一轮的验收机制暴露:

1) 编码取整与契约参考实现不一致(T-WIN-022)
   KeypointFrame.encode() 用 GDScript 的 roundi(半数远离零),而契约参考实现
   (Web 的 keypoint-codec.ts)与**生产发送方 Android**(Kotlin Math.round)都是
   「半数朝 +∞」:-2.5 分别是 -3 与 -2。实测在 12 个跨实现向量里 1 例 33 字节不同。
   本端是接收方、encode() 只用于自测与协议回归,对产品无影响;但它让「跨实现一致性」
   只能停留在宽松口径("差异仅限 .5 取整边界"),而宽松口径会退化成没人看的已知差异。
   修复:新增 _round_like_js(v) = floor(v + 0.5),用于 4 处取整(坐标 ×3 + 置信度);
   夹紧顺序对任意实数与参考实现等价。
   收紧:accept-frame-vectors.sh 的编码口径改为「必须为 0 项差异」。
   新增单测(+11 断言):_round_like_js 的 5 个取值、端到端 -0.5/32767 → 0(roundi
   会给 -1,是有效判别用例),以及 test_reference_vectors_decode_and_encode_exactly
   —— 直接读锁定的参考向量逐值解码 + 用 f32InputPoints 重编码与 f32Hex 逐字节比对,
   让 verify.sh(只跑源码、无需 pck)也覆盖「Web ↔ Windows」这条边。

2) 产物里夹带开发/验收工具(T-WIN-023)
   export_filter="all_resources" 且 exclude_filter 没有 build/*,于是每次新增
   构建/验收脚本都被编译进 pck —— 包括**故意不合规**的坏服务端夹具 probe-ws-bad.gd
   与 frame-vectors.json。实测 OpenDance.pck 315,464 B →(排除后)145,400 B,
   即 54% 的 pck 是测试夹具。已发布的 v0.2.3 同样带着这些残留。
   修复:exclude_filter 增加 build/*;
   新增产物级防线 build/integration/list-pck.gd(遍历包内条目、标出
   res://build/ tests/ _scratch/ dist-release/ 与 *.md 残留,有残留即退出码 1),
   并接进 accept-release.sh(打印条目总数并断言「无开发残留」)——否则下次加个新
   工具目录又会重演。顺带确认 pck 没有把上一次导出的 pck 自嵌套进去。

实测(v0.2.4 发布包,三条产物级验收全绿):
  * accept-release.sh:pck 58 项无开发残留 / PE 版本资源 0.2.4 / pck 启动 180 帧无错 /
    运行时探针(包内版本号 0.2.4、AboutScreen 显示值、15 项关键资源、契约表比对)
  * accept-ws.sh:客户端 30 通过 / 0 失败 + 服务端侧 16 项事实
  * accept-frame-vectors.sh:解码 12/12、396 点 0 差异,
    **编码器字节与参考实现完全一致(0 项差异)**
  * verify.sh:785 通过 / 0 失败(原 774)

踩坑:给 -0.5/32767 这类值写断言时,第一版按"理想有理数"期望(2.5/32767 → 3)而
失败 —— PackedVector3Array 存的是 float32,乘回 32767 后略小于半整数,与 JS 对同一
float32 输入的行为其实完全一致。断言必须基于实际存储精度,或改用有效判别用例。
This commit is contained in:
2026-09-17 05:59:54 +08:00
parent 1c5f28cd41
commit 6ea2c93d66
14 changed files with 401 additions and 33 deletions
+17 -5
View File
@@ -1,5 +1,5 @@
================================================================
OpenDance Studio -- Windows 客户端 v0.2.3 使用说明(zip 为 LZMA 压缩,需用 7-Zip/WinRAR 解压)
OpenDance Studio -- Windows 客户端 v0.2.4 使用说明(zip 为 LZMA 压缩,需用 7-Zip/WinRAR 解压)
================================================================
摄像头跳舞评分系统的核心体验端:接收 Android 辅助 App 通过 WebSocket
@@ -8,6 +8,18 @@ OpenDance Studio -- Windows 客户端 v0.2.3 使用说明(zip 为 LZMA 压缩
本客户端只接收关键点坐标,不接收、不存储任何视频画面。
v0.2.4 修订
1. 编码取整与契约参考实现对齐: 本端 encode() 原用 GDScript roundi(半数远离零),
而参考实现与生产发送方(Android 的 Math.round)是「半数朝 +∞」—— -2.5 分别是
-3 与 -2。本端是接收方(encode 只用于自测),故对产品无影响,但跨实现一致性
只能停留在"差异仅限取整边界"的宽松口径。现改为 floor(x + 0.5),并把验收口径
收紧为「编码差异必须为 0」。
2. 产物不再夹带开发/验收工具: export_filter="all_resources" 且 exclude_filter
没有 build/*,导致探针脚本(含故意不合规的坏服务端夹具)与向量文件被打进 pck ——
pck 从 145,400 B 涨到 315,464 B(54% 是测试夹具)。现已排除 build/*,
并新增产物级残留检查(accept-release.sh 会断言「无开发残留」)。
3. 无头测试 785 项断言(原 774)。
v0.2.3 修订
1. 补 Motion.thumbnail_url: 服务端 catalog/export 从 data-models 0.6.0 起一直
在发 thumbnailUrl,客户端类型里却缺这个字段(Model/Scene 都有),等于默默丢掉。
@@ -140,11 +152,11 @@ OpenDance.exe 的用户看第一节即可。
打成发布包:
bash build/package-release.sh 0.2.3
bash build/package-release.sh 0.2.4
得到 dist-release/ 下两个资产:
opendance-windows-v0.2.3.zip <- 单个完整包,禁止 .partN 分卷
opendance-windows-v0.2.4.zip <- 单个完整包,禁止 .partN 分卷
SHA256SUMS <- 裸文件名,可直接 sha256sum -c
包里含 OpenDance.exe、OpenDance.pck、THIRD_PARTY.md、README.txt、
@@ -163,14 +175,14 @@ OpenDance.exe 的用户看第一节即可。
如果你能把包放到别处分发(例如 Web 服务端的 /static,不受 IIS 那个
上限约束),建议改用资源管理器可直接双击解压的 deflate 包:
ZIP_METHOD=deflate bash build/package-release.sh 0.2.3 # 约 38 MB
ZIP_METHOD=deflate bash build/package-release.sh 0.2.4 # 约 38 MB
上限一旦放开,Release 资产也应换回 deflate 包。
7. 自检清单
0) 发布包级验收(对**发布包**而不是源码;文档 §7.5)
GODOT_BIN=/path/to/godot bash build/accept-release.sh dist-release/opendance-windows-v0.2.3.zip
GODOT_BIN=/path/to/godot bash build/accept-release.sh dist-release/opendance-windows-v0.2.4.zip
预期末行「发布包级验收全部通过」。它会校验 sha256、解压、核对文件清单、
读 exe 的 PE 版本资源、用 Godot 直接加载包内 pck 跑 180 帧、并跑包内运行时
探针(包内版本号 / 「关于」清单显示值 / 主场景 / autoload / 关键资源 /