# 阶段4最小真实玩法闭环102数据与cdTime兼容独立审查 日期:2026-09-24。审查者:ZCode会话。独立性声明:未参与本方案与任何实施;本轮只读+hash计算+源码/备份核对,仅新增本报告。 ## 受审输入核对 `KVGameplayLoopTests/102-compatibility-review-hashes.json`共92项,逐项重算——**全部一致**。102 PF源备份SHA256 `827F36084648449C…`与方案一致;空KV备份hash一致;导入proposal为**45条目**(每键含原始UTF-8字节数/值SHA256/前值absent)、`restoreDeleteKeys`45项、`transformValues=false`、状态`proposal-not-executed`。 ## 结论一:**批准单方法兼容修订(cdTime:null)** **事实链逐环独立核实**: 1. `PlayerShopData.cs:697`:每日刷新**显式赋值**`VIPAdPackData.cdTime = null;`——null是既有业务的合法主动输出,非历史脏数据; 2. `:1051`正常路径赋时间字符串、`:1060`消费端`TryParseDateTime(VIPAdPackData.cdTime,…)`本就容忍null——旧读写闭环对null自洽; 3. 新Schema `PlayerKVSaveSchema.cs:451`对`cdTime`一律`String(o["cdTime"])`拒绝JSON null——**是解码约束严于真实合法存档的偏差**,不是存档问题; 4. 102备份中`VIPAdPackData = {"ID":0,"index":0,"day":264,"cdTime":null,"isOpen":true}`与方案引用逐字一致。 **补丁评估**:`o["cdTime"]?.Type == JTokenType.Null ? null : String(o["cdTime"])`——仅放宽"字段存在且值为JSON null"一种情形为合法null;缺字段/数字/布尔/对象/数组仍Malformed;不转空串、不删档、不放宽全局String helper、不波及其他模块;下游`PlayerKVAdvertValue.Time`与`ReplaceFromKVDecoded`原样携带null(PlayerShopData:149/160已核实可空流转)。**最小、正确、边界严格。** 测试要求(§3.1真实null样例/普通串/各非法类型/其余字段严格不变)充分。 ## 结论二:**102初始化方案可执行** - 前置完备:空基线二次确认(非空即停)、PF源45项摘要校验、目标key清单落盘、`transformValues=false`保证逐值原样。 - 执行安全:现有`PlayerKVClient.SetAsync`单请求45键(服务端单SaveChanges事务);禁止额外键/PF写/自动重试;MayHaveCommitted→先Get核对不盲重发;全量Get逐值确认+导入后备份;运行许可以导入后备份生成、key范围限定45个、超范围自动写按R1合同停止。 - 恢复路径:仅Delete清单45键→Get确认空;清单外键即停不全库清空;PF原档全程不写;成功结果默认保留。 - 101另两类兼容问题(M04广告时间/M15 JSON null/M22 selections null)明确不在本轮——选择102的收敛理由成立(避免扩大兼容面)。 ## P3清单 - **P3-1**:导入步骤3"若MayHaveCommitted先Get逐项核对"——45键逐项核对建议同时记录"实际值==清单值"的逐键布尔矩阵(便于区分部分提交),实施工具已具备材料。 - **P3-2**:运行许可的key白名单(45键)与R1 §2.3"记录登录→装备全部KV变更key"联动核对时,注意初始化自动写可能更新既有键的**值**(同键新值在白名单内)——核对规则应按"键∈45"而非"值不变",方案§4.4已隐含,建议实施日志明示一句。 - **P3-3**:cdTime补丁落码后须重跑的4B2离线75组/Unity M04用例/B2-20/装备链9组清单已在§3.2列明——执行时保留任何首败。 ## 边界重申 本轮仅为兼容差异与数据初始化审查:不构成R1实施关闭、不申请101兼容、不建通用迁移框架、不启用消费4C/热换号;真实运行(导入→登录→装备→重启恢复)待主会话裁决+用户继续指令后执行,其后按既有模式做R1独立实施复核。P2-α存量真实用户专项与4D/G4启用门保持。