Files
ft/CodexOutput/upserver/阶段3A独立代码审查-2026-09-22.md

86 lines
8.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 阶段 3A 独立代码审查
日期:2026-09-22。审查身份:主实现会话之外的独立审查 agent。
## 1. 最终裁决
**限定阶段 3A 通过。** 发现的 1 项 P2 路径校验问题已经由主会话修复并经独立回归确认;当前三文件没有剩余已证实阻塞问题。可按已批准方案继续阶段 3B,不能据此宣称整个阶段 3 或生产游戏 KV 切换完成。
本次只审查同步状态、快照格式和本地文件持久化,不修改生产代码,不调用正式服,不操作 Unity。独立证据写入 `KVSyncReviewTests/`;主会话测试和编译证据只读核对。
## 2. 对照依据及代码范围
方案:《阶段3缓存同步方案与评审-2026-09-22.md》,重点第 4–7 节与 G3A;此前方案独立审查的问题已闭环。用户本轮确认继续后,两项保守策略已经批准:未知写不得仅凭 Get 自动解锁;损坏主档不得自动恢复旧备份并继续写。
本次生产文件均在 `Client/Assets/Scripts/Services/PlayerData/`:
| 文件 | 实际审查范围 | 最终 SHA256 |
|---|---|---|
| PlayerKVSyncModels.cs | 身份规范化、不可变对外模型、快照编解码、序号及批次关联 | `49143F3A6DAD9A570C522288B471D5C4CE5812F73E0EB7B8E6081453C97990D4` |
| PlayerKVCacheStore.cs | 独占锁、加载失败分类、临时文件/flush/原子替换、失败与释放 | `A08DAB00F51A28CB5AA9A26D66CB3EB9349216535E92F4DC4E77EE8DDEBA28B1` |
| PlayerKVSyncState.cs | 状态转换、基线/待写/本地覆盖、多版本确认、未知恢复、同步 gate/Dispose | `B0BF9EBAA24C8ACB4761B7C09331B81A414E62CDBBF143B106B7F466E334A198` |
未将 owner、HTTP 串行调度、异步票据、Close 准入门判定为“缺失实现”:这些明确属于 3B。未扩大到 UserService、PlayFabMgr 或游戏存档接线。
## 3. 发现项及闭环
### R1 — [P2,已修复] Windows 半绝对路径通过缓存根目录校验
- 位置:`PlayerKVSyncModels.cs:101`,`KVIdentity` 的根路径检查。
- 初审实现使用 `Path.IsPathRooted`。Windows 上 `C:relative` 与 `\relative` 均可返回 true,但并非完整绝对路径;随后 `GetFullPath` 根据当前目录或当前盘符解析。同一参数可能指向不同命名空间,不符合 G3A1 的非法路径拒绝约定。
- 最小复现:向身份构造/Open 传上述根路径。正常完整绝对路径是对照。问题仅在调用方提供这种非法根目录时触发,没有证据表明现有正常 persistentDataPath 已因此丢数据。
- 主会话修复:改为 `Path.IsPathFullyQualified`,不改变存储格式或同步算法。独立宿主断言两类路径均拒绝;主测试增加对应两项;Unity 编译证据确认该 API 在当前项目可用。
- 证据边界:修复发生在独立宿主首次执行之前,因此未伪造“旧源码执行失败”记录。旧实现由初审源码及明确的 Windows 路径语义确认;本报告保存的是修复后实际执行结果。
另有初审文档状态提醒:方案末尾一度残留“待用户确认/尚未实现”的旧总结,已反馈主会话同步。此项不属于生产代码缺陷。
## 4. 关键正确性核对
| 风险 | 核对结果 |
|---|---|
| 丢失已接纳编辑 | 每次编辑先克隆快照,保存成功才发布新内存和 Success。失败进入 StorageError,后续编辑/同步启动被拒绝;无失败后静默清队列路径。 |
| 本地提交不确定 | `Save` 在替换前设置不确定标记;替换后故障返回失败并保留原内存,同时报告目标 revision/attemptSequence 和不确定性。重开按实际主文件恢复,不强行认定本次编辑未保存。 |
| 损坏加载或错误身份 | 必填类型、未来版本、身份、重复 JSON 属性、完整根、序号界限、待写唯一序号及批次关联均有检查。损坏返回 RecoveryRequired 并释放独占句柄;不把损坏读成空字典。 |
| 备份退回旧数据 | 有效主文件优先;损坏/缺失主文件且有遗留材料时阻止打开,不自动接受备份。有效主文件不因损坏备份而冻结。 |
| active 与 v2 混淆 | 批次是不可变快照。v1 发出后可保存 v2;确认仅移除同 sequence,否则保留 v2 的目标并推进 base 至 v1。合法同 key 同 sequence 的引用可加载。 |
| unknown 在重开时丢失 | 重开遗留 active 在内存转换为 unknown;原磁盘 active 本身仍是再次重开的冻结证据。下一次保存才写成 unknown 不形成放行窗口。R=B/R=L 均不能清未知批次。 |
| 普通冲突误判损坏 | 最新 baseline 可是远端冲突观察值,而 pending.BaseValue 仍是编辑时基线;二者不要求始终相等。独立用例覆盖这个合法状态重开及重复冲突,不建议加入错误的无条件相等校验。 |
| remoteStore=false | 只形成 localOnly;不取消既有远端 pending,不被旧批次确认覆盖。显式远端 Update 或 Delete 同次提交清除对应覆盖。 |
| 锁/Dispose 竞态 | 状态操作和保存受同一同步 gate 保护,Dispose 也使用该 gate,重复 Dispose 不释放新实例的锁。3B 必须在释放此同步状态前排空已准入网络工作;本层不冒充已实现该异步生命周期。 |
## 5. 独立执行证据
独立宿主:`CodexOutput/upserver/KVSyncReviewTests/KVSyncReviewTests.csproj`。它直接编译上面三个生产 `.cs` 文件,引用项目现有 Newtonsoft,未用复制/镜像状态机代替实现,也没有 HTTP 代码或 Unity 自动化。
最终执行:**13 组场景、127 个断言全部通过**。组数与断言数不同,不能描述成 127 个独立完整业务场景。
证据目录:`CodexOutput/upserver/KVSyncReviewTests/Evidence/20260922-072831-309/`,汇总 `Latest-review.log` 含断言与源码 hash;入口控制台结果为 `KVSyncReviewTests/Latest-console.log`。首次执行证据另存于 `Evidence/20260922-072648-825/`,未覆盖。
覆盖重点:
- 完整绝对路径对照及 Windows 两类非法根路径拒绝。
- active v1 + pending v2 重启,R=B/R=L 不解锁,v1 确认推进 v2 base。
- localOnly 叠加、确认不覆盖及 Delete 清覆盖。
- 五个磁盘故障点:BeforeWrite、AfterWrite、AfterFlush、BeforeReplace、AfterReplace;内存不发布、冻结、实际磁盘重开与不确定标记。
- 数字溢出、字段类型、重复字段和尾随根拒绝;每次拒绝后修复测试材料并重新打开,验证句柄未泄漏。
- 12 种批次关联损坏(包含双 active/unknown、无对应 pending、目标/base 不符、非法批次 ID/结构等),以及合法同序号/更新序号的对照。
- 普通冲突 B 与最新远端观察不同的合法快照重开。
- 有效主档/损坏备份、缺失主档/遗留备份、独占锁和重复 Dispose。
上述磁盘数据均为合成测试字符串,根目录均在审查目录,没有读取或写入真实游戏缓存。URI 只作为身份字符串使用,没有网络请求。
## 6. 主会话证据的只读复核
- 已阅读 `KVSyncTests/Program.cs` 和 `KVSyncTests/Latest.log`:**86 通过、0 失败**。其中另含真实子进程独占锁、写步骤进程退出、101 个 key 分批、24 个并发编辑、超限文件以及更多输入/恢复用例。本 agent 没有重跑或改动主测试。
- 已读取 `kv3a-unity-compile.json`:`Success=true`,`ErrorCount=0`,`WarningCount=274`。本 agent 没有启动或控制 Unity;这是主会话执行并落盘的编译证据。
## 7. 后续门与限制
1. 3B 验证真实 PlayerKVClient 配可控传输、固定会话、票据精确确认/Superseded、水位、取消和 Close 原子准入;不能用本次同步 gate 用例替代异步关闭验收。
2. 3C 再做组合和限定联调;本次没有进行正式服 KV 写入或 Unity 业务存档运行验收。
3. Windows/.NET 文件故障和进程退出测试不证明移动设备文件替换、文件锁错误分类及断电耐久性。当前 Unity 编译成功也不等于最终平台文件系统验收;真机/最终包按既定计划单列,当前不打包。
4. Json.NET 扩展语法继续按阶段 2/方案约定兼容;结构校验不是防篡改签名,也不能识别所有仍满足格式的外部内容改写。本轮不新增手写 JSON 解析器或密码学完整性机制。
5. 本地 Ordinal 字典不保证服务端数据库 collation 区分大小写;服务器仍无 CAS。不得扩展为跨设备强一致保证,实际生产 key 和桥接安全门留阶段 4。
**收尾结论:R1 闭环,3A 限定代码审查通过;下一步是已批准范围内的 3B 开发与独立验收。**