# 阶段 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 开发与独立验收。**