@@ -5,7 +5,7 @@
阶段 0 已经完成(骨架,见下);阶段 1 已完成(开发机 PoC,见下);阶段 2、3、4、5 已完成(见各节);
**阶段 6 已完成(运行正确性与失效状态) ** ,依据是对 `6de6b8b` 的独立审查
( `_ review_ scene3d_ 20260914/ review.md` )与其可控复现。**阶段 7 已完成(二维图像后端统一 + 回放入口收口)**、
( `D:\orisys_ws\docs\archive\ reviews\ scene3d- 20260914- review.md` )与其可控复现。**阶段 7 已完成(二维图像后端统一 + 回放入口收口)**、
**阶段 8 第一批已完成(能力控件、真实色标、复位语义、命名) ** 、
**阶段 9 上半已完成(限速、真实统计、无位移复用几何、保护包密钥注入) ** 。
未完成的两项写在这里,不藏在细节里:**阶段 8 第二批(画布布局:2D/3D 页签容器、参数抽屉、窄窗口回退、
@@ -109,7 +109,7 @@ sha256 + 原子写入 + 读取时先验签再相信)、两个工具(`validat
| **重新计算几何 id ** | 换掉顶点数组并把所有哈希改成自洽后,仍被拒——manifest 的 geometry_id 必须等于**包内数组**的摘要 |
| 外壳 GLB | 节点变换烘焙进顶点、法线用逆转置并归一化、缺法线则计算、三角形预算超限报 `gpu_budget_exceeded` |
`compile_scene.py` → `validate_scene.py` 端到端在本机跑通(见 `.repro` 之外的 仓库内工具;
`compile_scene.py` → `validate_scene.py` 端到端在本机跑通(见仓库内工具;
产物示例:1032 顶点包,`geometry_id` 与 `asset_hash` 见提交信息)。
**这一阶段抓到的 ** :
@@ -313,6 +313,11 @@ shared 全部 **262 项**。`ui_check.py` **566 项检查 0 失败**(新增 "3
| **性能 ** | `docs/architecture/perf-report-windows-dev.json` : 1032 顶点实测资产 compose p50 **0.50 ms ** / p95 0.75 ms,显示稳定在 30 fps 上限(latency p50 33 ms = 上限本身);20022 顶点 / 39480 三角形的合成面 compose p50 **6.15 ms ** / p95 6.40 ms(约 33 ms 帧的 18%, GPU 缓冲约 1.76 MB);采集线程侧 `submit_packet` p50 0.13– 0.17 ms、p95 < 0.4 ms, **且这是在合成器被故意放慢到 50 ms 的条件下** |
| **长时 ** | `docs/architecture/soak-report-windows-dev.json` :无窗口 10 分钟 60 fps( 35 980 帧)RSS 40.4→41.8 MB、首末四分位增长 1.35 MB、尾段速率 **0.354 MB/min ** ;真实 GL 窗口 4 分钟 30 fps( 7 200 帧)RSS 186– 200 MB(驱动+窗口系统为主)、增长 2.83 MB、尾段速率 **0.809 MB/min ** ;两者 mailbox 容量 1、同时最多一次合成,丢帧一律计为**显示**丢帧(无窗口 5 647/35 980, GUI 19/7 200) |
> 注(2026-09-27):`perf-report-windows-dev.json` 里 `entries[].scene` 记录的是生成时所用的
> 临时包路径 `D:\orisys_ws\.repro\build\finger-display-1.0.0.oryscene`( `.repro\` 已删除)。
> 该字段只是探针的输入出处,报告中的**测量数字不受影响**;报告本身是 `--lock-from-probe`
> 的输入,因此保持字节不变,这里只作说明。重新生成请用 `tools/scene_assets/bench_scene.py`。
`test_scene3d_protect.py` 34 项(封套/签名/篡改/密钥/锁定/记录块/端到端发布流程),
`test_scene3d_view.py` 30 项,`test_scene3d_package.py` 20 项(含 v1↔v2 与"密文需要 provider"),
其余同阶段 4。全仓计数:apps/studio **193 项 ** ( 3D 相关 102 项)、shared **297 项 ** ( 3D 相关 138 项)。
@@ -376,7 +381,8 @@ shared 全部 **262 项**。`ui_check.py` **566 项检查 0 失败**(新增 "3
## 阶段 6:运行正确性与失效状态(批次 A)—— 已完成
依据:对 `6de6b8b` 的独立审查(`_ review_ scene3d_ 20260914/ review.md` )给出的 P1 项 R1/R2/R3/R7。
依据:对 `6de6b8b` 的独立审查(`D:\orisys_ws\docs\archive\ reviews\ scene3d- 20260914- review.md` )给出的 P1 项 R1/R2/R3/R7。
(该审查的复现脚本与 `pytest-tmp` 属于一次性工作区临时物,已在 2026-09-27 的工作区整理中删除;审查正文已归档,下表的验收证据不受影响。)
审查看法经逐条核对后有两处修正:报告提到的 `BindingInformation` 在仓库中不存在(对应物是
`contracts.SurfaceBinding` );`finger_worker.py` 在 `apps/studio/shared` 一侧而不在 SDK,且
`compute_error` 是局部变量。`valid=False && flow 非空` 有两种成因(读取失败时 `flow=None` ;
@@ -427,14 +433,14 @@ shared 全部 **262 项**。`ui_check.py` **566 项检查 0 失败**(新增 "3
( geometry_id 仍是 `1a2e0e92…` 、1032 顶点 / 1974 三角形,新增 `source_geometry_id=46a03a5f…` ,
asset_hash `dbdf861c…` → `ea4beab6…` )。新增 locale `scene3d.state_stale` (中英各一条)。
**验收(已通过) ** :
**验收(已通过;下表的探针脚本 `.repro/probe_stage6_*.py` 已随工作区整理删除,表中记录的是它们当时跑出的结果 ) ** :
| 用例 | 结果 |
|---|---|
| R1 停止后旧任务复活 | 可控复现反号:`.repro/probe_stage6_r1.py` → `stopped_frame_returns` 由 `{valid_after_old_worker_finishes: true, state: "live"}` 变为 `{false, "no_data", epoch_bumped: true, slot_free_again: true}` ; 20 轮 begin_session→submit→tick→show_rest 循环里最后一个画面上永远没有有效测量,`max_in_flight==1` |
| R1 停止后旧任务复活 | 可控复现反号:`.repro/probe_stage6_r1.py` (已删除) → `stopped_frame_returns` 由 `{valid_after_old_worker_finishes: true, state: "live"}` 变为 `{false, "no_data", epoch_bumped: true, slot_free_again: true}` ; 20 轮 begin_session→submit→tick→show_rest 循环里最后一个画面上永远没有有效测量,`max_in_flight==1` |
| R7-b request_id | 同一探针:`request_id_not_checked` 由 `{old_submit: "accepted", shown_request: 1}` 变为 `{old_submit: "stale", shown_request: 2, diagnostic: "stale_frame"}` ;"较旧请求的结果晚到"在接收侧也被丢弃 |
| R2 失效字段 | 探针 `.repro/probe_stage6_*` 与单测:`flow_valid=False` (带 `invalid_reason` )→ 拒绝并报 `field_stale` ;未声明 → `field_unverified` ; `flow_frame_id` 落后 → `field_stale` ;设备 mask 域不符 → `field_domain_mismatch` 拒帧;compose 抛错 → `stale` + 诊断,好帧恢复 `live` ;宽限内保留画面、到期回参考模型 |
| R3 设备几何 | 探针 `.repro/probe_stage6_device.py` → `probe_stage6_device.json` (真实 bundle + 真实包):设备描述 `verified=true` 、domain `feb7f71e…` 、source geometry `46a03a5f…` 、300x280、米制 id 未声明;发布包通过该描述;**同尺寸不同映射**(只改 map 一个像素)→ domain 变化、shape 不变、包被 `field_domain_mismatch` 拒绝;设备什么都不声明 → 接受 + `geometry_unverified` |
| R2 失效字段 | 探针 `.repro/probe_stage6_*` (已删除) 与单测:`flow_valid=False` (带 `invalid_reason` )→ 拒绝并报 `field_stale` ;未声明 → `field_unverified` ; `flow_frame_id` 落后 → `field_stale` ;设备 mask 域不符 → `field_domain_mismatch` 拒帧;compose 抛错 → `stale` + 诊断,好帧恢复 `live` ;宽限内保留画面、到期回参考模型 |
| R3 设备几何 | 探针 `.repro/probe_stage6_device.py` (已删除) → `probe_stage6_device.json` (真实 bundle + 真实包):设备描述 `verified=true` 、domain `feb7f71e…` 、source geometry `46a03a5f…` 、300x280、米制 id 未声明;发布包通过该描述;**同尺寸不同映射**(只改 map 一个像素)→ domain 变化、shape 不变、包被 `field_domain_mismatch` 拒绝;设备什么都不声明 → 接受 + `geometry_unverified` |
| R7-a 加载请求 | 单测:忙时第二个请求成为 pending 并在第一个结束后运行(请求号递增)→ 面板丢弃过期完成 → 失败后可重试 |
| 回归 | apps/studio **234 项 0 失败 14 跳过 ** (跳过的是 offscreen 下的真 GL 用例)、shared **316 项 0 失败 1 跳过 ** ;真 GL 冒烟 `QT_QPA_PLATFORM=windows` **14 项 0 失败 0 跳过 ** ; `ui_check` 587 项 0 失败;`locale_check` 0 缺失;`validate_scene.py` 对重编包全项 ok |
@@ -476,7 +482,8 @@ shared 全部 **262 项**。`ui_check.py` **566 项检查 0 失败**(新增 "3
- **重编包改变 `asset_hash` **( `dbdf861c…` → `ea4beab6…` , geometry_id 不变):旧录像的
`visualization3d` 块只是记录,不影响读取;`session.json` 的块版本未变(只增键)。
- 审查用的复现脚本里 `coordinator._inflight` 被当作 Future 使用,现在它是 `_Inflight` 记录,脚本无法
原样运行;等价探针(`.repro/probe_stage6_r1.py` )覆盖同样的两条结论并留在 `.repro/` 。
原样运行;等价探针(`.repro/probe_stage6_r1.py` )覆盖同样的两条结论——该探针与整个 `.repro/`
目录已在 2026-09-27 的工作区整理中删除,两条结论以本节表格为准并已由仓库内单测覆盖。
- **真机待验证一项**:算法链失败时 SDK 的 `VRAW` (光流)是否也过期。当前实现取保守解释(链失败即本帧
派生量不可声明);若实测证明 `VRAW` 仍可靠,`flow_valid` 放宽为只看读取结果是一行改动。
- 长度单位仍只在编译期:设备侧不声明米制几何,`ExpectedGeometry.geometry_id` 留空,绝不猜。