收紧资源布局 revision IPC 精度边界

统一限制资源布局 revision 到 JavaScript 最大安全整数
在 Rust serde、Tauri 输入与前端 IPC 三层拒绝非安全 revision
补充最大值往返、上限失败、超限零副作用与不可信响应回归
同步更新资源画布合同、技术决策与竞态经验
This commit is contained in:
2026-07-31 11:27:23 +08:00
parent 0c817383b8
commit beec99a3b7
10 changed files with 283 additions and 18 deletions
@@ -3888,6 +3888,14 @@
- 验证:定向 Hook 测试固定“resource sync revision 1 在途、manual 排队、权威 revision 2 conflict、resource retry 成功”时序,断言 retry 使用 revision 2、权威坐标保留、旧 manual 不重放且 notice 仍存在。
- 关联:`apps/ai-game-creator-shell/src/view/project-development/useProjectResourceCanvasLayout.ts`、`apps/ai-game-creator-shell/tests/useProjectResourceCanvasLayout.test.ts`。
## Rust u64 revision 不能直接穿过 JavaScript number 边界(2026-07-31)
- 现象:资源布局 sidecar 的 revision 在 Rust 中可增长到完整 `u64`,但经 JSON / Tauri 返回 TypeScript 后只能用 `number` 表示;超过 `9_007_199_254_740_991` 时相邻整数会折叠为同一值,窗口可能持续 conflict,甚至用失真的 expectedRevision 破坏 CAS 判等语义。
- 原因:Rust 的 `checked_add` 只防止 `u64` 溢出,不能证明序列化后的整数仍能被 JavaScript 精确表示;纯 Rust `u64::MAX` 测试没有经过真实跨 JSON 合同。
- 处理:保留 Rust `u64` 存储类型,但把共享合同合法域冻结为 `0..=Number.MAX_SAFE_INTEGER`。共享 DTO 对 revision 自定义 serde 校验,Tauri 更新在任何项目或锁副作用前验证 expectedRevision,sidecar 读取拒绝超限值,前端在 IPC 读取、更新响应和请求发送前重复验证非负安全整数;达到上限时写入失败且 sidecar 字节不变。
- 验证:Rust 与 TypeScript 合同测试分别覆盖最大安全值往返、最大值加一拒绝;Tauri 持久层覆盖超限 expectedRevision 零 workbench 副作用、超限 sidecar 原字节保留和最大安全值递增失败;Hook 覆盖不可信读写响应不能进入 CAS。
- 关联:`server-rs/crates/shared-contracts/src/game_creation_app.rs`、`packages/shared/src/contracts/gameCreationApp.ts`、`apps/ai-game-creator-shell/src-tauri/src/project/resource_layout.rs`、`apps/ai-game-creator-shell/src/view/project-development/useProjectResourceCanvasLayout.ts`。
## 抽通用 Runtime 时不要把产品持久文件直接变成公共 ABI
- 现象:为了快速“抽 crate”,直接把 Tauri package 内的 `AgentRuntimeState`、sidecar struct 或 Runner protocol 改成 `pub`,第二个消费者虽然能编译,却同时绑定游戏 schema、UI 投影、文件路径和未稳定恢复顺序。