9.6 KiB
9.6 KiB
阶段3技术方案独立评审(ZCode 会话)
日期:2026-09-22。评审人:ZCode 主会话(应用户"对阶段3技术方案做一下评审"要求执行)。评审对象:《阶段3缓存同步方案与评审-2026-09-22.md》全文、既有独立方案审查闭环,以及方案所述边界与当前工作区实际状态的一致性。本轮只读核查与落盘本文件,未修改任何生产代码、状态文档或测试。
裁决摘要
技术方案内容:通过(含对 R1–R4 闭环的复核)。两条收紧策略:建议用户确认(附条件,见第四节)。但存在一项 P0 级存证失真和一项 P1 级验收门未闭合,必须在推进 3B 前纠正。
方案本身的工程质量高:写前日志、单写者租约、原子替换、快照严格校验、B/L/R 三方比较、未知保守冻结等合同完整自洽,且已写出的 3A 代码与方案逐项吻合。问题不在设计,在于文档记录的工作状态与工作区实际状态已经分叉。
一、P0:存证与实际状态失真(阻塞 3B 放行)
时间线(文件 mtime 取证):
| 时间 | 事件 | 证据 |
|---|---|---|
| 15:01 | 接手入口/开发状态/TODO 落盘,均写明"本轮仅文档、无生产代码修改或测试执行、待用户确认后进入3A" | 三文件 mtime 2026-09-22 15:01:41 |
| 15:03 | 独立方案审查终验完成,记录主方案 hash 097EE094…,明确"用户确认与3A实施仍未勾选" |
阶段3缓存同步独立方案审查-2026-09-22.md |
| 15:14 | 主方案被再次修改:顶部改为"用户本轮'继续'已确认新策略,现进入3A实施",检查表勾选用户确认 | 当前 hash 70c7C5D8… ≠ 审查终验 hash |
| 15:19–15:25 | 3A 三个生产文件写入(PlayerKVSyncState/PlayerKVCacheStore/PlayerKVSyncModels) | 文件 mtime |
| 15:24 / 15:27 | KVSyncTests 执行:74 项、86 项全部通过 | Initial.log / Latest.log |
三个具体问题:
- "用户确认"依据不足且自相矛盾。 主方案顶部称用户以"继续"确认两条收紧策略,但同文档底部结论仍写"待用户确认两项策略,生产代码尚未实现";独立审查明确要求"这两条不能由独立技术审查替代用户确认,也不能由历史G1推定"。本轮用户实际动作是要求评审方案,不构成对该两策略的确认。修改发生在独立审查终验 hash 之后,未经复核。
- 状态文档与实际相反。 15:01 的三份状态文档声明无生产代码与未执行测试;实际 3A 已实现且 86 项测试已通过。任何后续接手者按文档理解会被误导,违反项目自身落盘协议。
- 3A 实施事实缺正式记载。 86 项测试通过没有对应验收文档,未记载与方案 G3A 用例矩阵的覆盖对应关系。
整改要求(进入 3B 前): ① 用户对本报告第四节明确表态;② 主方案顶部/底部及三份状态文档按实际状态改写一致,"用户确认"以用户的明确表述为准;③ 3A 已实施事实按实际补记载(文件清单、测试证据、未完成项单列)。
二、P1:G3A 验收门未闭合
按方案自设验收门,3A 完成需要"状态转换、磁盘故障、隔离及重启恢复测试,Unity 兼容编译"与独立 review。当前:
- 离线测试 86 项通过(合成 fixture,含磁盘边界故障注入、租约跨进程、损坏快照拒绝、序号溢出等);
- Unity 编译验证缺失(现有 kv-unity-compile.json 为阶段2证据,不含三个新文件);
- 3A 代码独立复审缺失(本报告评审了方案与代码一致性,不替代按 G3A 清单的逐项验收);
- G3A 验收报告未落盘。
三、技术评审结论
3.1 通过项(方案与已写代码逐项核对)
| 领域 | 核对结果 |
|---|---|
| 写前日志 | BeginBatch 先 Commit 落盘再暴露批次(batch = snapshot.Active 在 Commit 成功后),符合§7.1 |
| 批次规则 | sequence 升序、连续同类型、≤10 key:TakeWhile(Exists==首项).Take(10);解码校验同规则 |
| v1/v2 并发 | ConfirmBatch 精确 sequence 移除、v2 基线推进 WithBase(v1);与§7.1 一致 |
| B/L/R | R==L 确认移除、R==B 保留、均不等→Conflict;unknown 优先且不因观察解除;整次合并单次落盘 |
| 磁盘顺序 | tmp→Flush(true)→File.Replace(保留bak)/首次Move;mayHaveCommitted 窗口覆盖 AfterReplace 故障注入 |
| 快照校验 | 身份绑定(api/playerId 必须匹配)、sequence 唯一且<NextSequence、批次-pending 关联(含被替换旧 sequence 的合法引用)、≤10/同类型/升序、64MB 上限、未来版本拒绝 |
| 遗留证据 | 主档缺失但有 bak/tmp → RecoveryRequired;主档有效时 bak 损坏仅忽略;不静默建空档(Get 失败不 Ready) |
| 会话隔离 | 构造时清 AuthenticationInvalid 但保留 Unknown;Active 遗留转 Unknown;与§5"重登不能只改枚举恢复"一致 |
| 取消语义 | R2 已在状态层落实(等待者取消不影响事实,由 3B 包装 WaitForTicketAsync) |
| 对现有代码断言 | PlayFabMgr 缓冲桶+每桶10key+40s 周期、失败仅日志;UserService 私有 apiSession/LoginLifetime;CustomServerMgr SessionVersion;S101AccountSession 每次 Login 新 CookieContainer——全部属实 |
3.2 保留意见(不阻塞,需在 3B/3C 或措辞中处理)
- P2|4xx 永久冻结的运营代价。 非 200 一律 MayHaveCommitted=true,叠加政策1(无自动解锁),单次服务端 400(如 key/值超限被拒)将永久冻结该账号命名空间,且本批不含人工恢复工具。建议:(a) 只读核查 N3-Server-CN 源码,若可证明 400/413 为"先校验后写",以差异裁决将其降级为确定未提交;(b) 将"诊断导出+人工解锁流程"列为 3C 交付或紧随其后的必做项。
- P3|Unix/Android 跨进程租约失效。 FileShare.None 在 .NET/Unix 不跨进程强制;Windows 双进程 Busy 测试通过,同进程互斥(主要风险:同进程换号未关旧 owner)仍有效。需在最终包平台差异清单明示。
- P3|UnknownOutcome 分支 baseline 被观察值覆盖。 Reconcile 在 unknown 分支将 baseline 更新为本次远端观察 R。写入已冻结故当前无实害,但 baseline 语义由"最后确认远端"漂移为"最后一次观察",未来若引入解锁机制会误导 B/L/R。建议统一:unknown 分支保留原 baseline,观察仅入 conflictObservations。
- P3|3B 次序合同。 批次在途时 RecordReadFailure/Reconcile 被 Active!=null 阻塞(状态机有意为之);3B 协调器必须先提交成功批次的 ConfirmBatch、后记录 401 失效,否则成功写会被冻结为 unknown(保守但损失可用性)。应写入 3B 合同测试。
- P3|ReadLocal 每次全量拷贝。 51+ key O(n) 拷贝对高频玩法读有成本,阶段4接入时如需可加只读缓存视图。
四、两条收紧策略裁决建议(待用户确认)
- 未知写不自动解锁(即使 Get 观察等于基线/目标)。建议确认。 服务端无 revision/CAS/幂等查询,任何"看起来没写"都不能排除迟到提交;自动重发的最坏后果是资产重复扣减。代价(可能永久冻结)应由后续服务端终态接口或恢复工具解决,不应由客户端猜测。附带条件见 3.2-1。
- 主缓存损坏时备份不自动作为可写恢复源。建议确认。 备份可能缺最后一次已接受修改,自动续写等于静默丢数据;RecoveryRequired+保留证据+人工恢复是正确取向。附带条件:人工恢复流程文档应尽早补齐,不能长期只冻结无出路。
五、建议放行顺序
- 用户对第四节两条策略明确表态(确认或修改)。
- 按第一节整改要求修正全部状态文档与主方案的自相矛盾。
- 补 G3A 门:Unity 含三新文件的编译验证、3A 代码独立复审、G3A 验收报告。
- 之后按方案进入 3B(固定会话及同步器),3B/3C 仍按小阶段验收推进。
证据清单
- 主方案当前 SHA256:
70C7C5D8D826964CE46159E295A150B74113431CAF33CB967CF28A5E624FF75F(独立审查终验记录为097EE094…,证明终验后又被修改)。 - KVSyncTests:Initial.log 74 通过 / Latest.log 86 通过,0 失败,仅合成 fixture。
- 已读核对的代码:Services/PlayerData 全部 5 文件;PlayFabMgr 缓冲实现;UserService/CustomServerMgr 会话标识;S101AccountSession Cookie 处理。
- 本轮未执行:Unity 编译、正式服访问、生产代码修改。
更正注记(2026-09-22,用户裁决后由主会话补充)
- 第二节 P1“G3A 验收门未闭合”已过时:Unity 编译(kv3a-unity-compile.json,0 错误/274 警告)、《阶段3A独立代码审查-2026-09-22.md》(最终限定通过)与《阶段3A缓存状态与磁盘验收-2026-09-22.md》均在本报告评审时点前后落盘,G3A 门已闭合。该发现反映评审时点,不代表当前状态。
- 第三节 3.2-3 为误报,撤回:复核 PlayerKVSyncState.Reconcile,unknown 分支在 baseline 更新语句之前 return,原 baseline 保留、观察仅入 conflictObservations,与方案 §6 一致,实现正确。
- 第一节 D2 相关判断部分过时:本报告依据 15:28 前的文件快照判断“三份入口文档未同步、开发日志与事实不符”;实际同步于 15:32/15:38 完成,系并发观察时序差,开发日志原记录准确。3B 亦已于其后开工(分工实施,实施记录另列)。
- “用户确认依据不足”已解决:用户 2026-09-22 正式追认两条收紧策略,定性“用户后续确认”(见接手入口顶部裁决);相关状态文档已按事实修正。