# M2架构复审裁决与修复顺序 日期:2026-09-29,主会话。依据[原ZCode独立审查](M2-纠偏与底稿独立审查.md)、[既有纠偏意见](M2-KVMgr层级依赖纠偏意见-待审.md)和当前源码。审查报告SHA256:`ABABB99EEE22D4E50A038A91AA5AF6D484E21F32546C6767F4A276031F62891A`;报告没有逐项受审manifest,故仅核其引用的源码事实,不把“只读+hash”解释为一个不存在的完整方案封板。B02四入口交付manifest本轮复算仍为44/44。本裁决**接受架构问题,未批准任何M2生产代码**。 > **后续用户指令对执行顺序的修正**:本文件R1/R3中“先归位KVMgr并同批处理Guard归属”的建议撤回,不能作为编码许可。先按[同生态位策略最新纠偏](M2-管理器同生态位替代策略-2026-09-29.md)制定纯迁移方案:保持现有Guard位置、状态、计数、拒绝结果及四入口方法体;逐项承接旧存档能力与调用方,仅处理后端差异所必需的适配。待迁移完成且验证稳定,再另立Guard/目录/架构优化方案并评审。原ZCode报告及本文件以下历史裁决保留作为问题证据,不把架构整洁性当成本轮迁移前置。M2生产代码仍未批准。 ## 一、逐项裁决 | 报告结论/建议 | 主会话裁决 | |---|---| | B02行为等价PASS不代表层级合理 | 接受。B02限定关闭不撤销,但不得据此继续把上层业务编排塞进KVMgr。 | | `Core/KVMgr.cs`→`Services/PlayerData`方向不清 | 接受。当前KVMgr对存储类型的依赖在物理位置上逆向;应使KVMgr与Handle/Owner处于同一存储模块,业务和登录Service从外部依赖它。 | | KVMgr调用guard就是调用上层Service,须新建/下沉guard | **限定接受问题,修正实现推论**。`PlayerKVGameLoadGuard.cs`本身只依赖`System`/`Threading`,没有调用Coordinator、UserService或业务;Coordinator控制一个存储准入门是正常向下调用。不能仅凭调用关系就新造第二套guard状态。优先保留现有单一guard的行为、计数和Close语义,调整其归属与KVMgr位置;若审查具体方案证明必须抽取,再列明确替换白名单。 | | Guard“21处引用”需逐项映射 | 接受映射要求。当前`PlayerKVGameLoadGuard.`限定方法调用实测**20处/5文件**:旧PlayFabMgr 11、KVMgr 4、GameLoadCoordinator 1、Editor循环2、验证宿主2;另有类型声明/参数引用,不和方法调用混算。见下表。 | | 正式Player可写handle没有交接出口 | 接受。`PlayerKVLoginContext.handle`私有,`TryAcquireAccountLease`是账号网络租约;`GameLoadCoordinator`结果不携handle,31模块现行游戏绑定仅Editor。正式路径需显式交接,不能从`KVMgr`反查Service或借测试循环静态句柄。 | | 224候选/81文件与四波分流 | 接受作**盘点**,不是可替换调用数或实现范围。M2-A不得把20个读/初始化候选一概当普通标记。 | | 首份方案合并“架构+handle交接+首批普通标记” | 接受**一次合并评审**,但首个业务验证优先复用已关闭的B01通知/俱乐部标记,不为了凑新调用数引入额外业务;是否新增普通标记要在上游核证后列白名单。正式默认切换仍有T08/账号政策等独立前置。 | | 底稿尚不可批准编码的五项原因 | 全部接受。当前没有M2实施许可。 | ## 二、当前与目标依赖图 当前(实线表示现有调用;目录是现状,不等于独立程序集): ```mermaid flowchart LR B[玩法与UI] --> PF[PlayFabMgr
Core/ 旧PF存档] B --> S[业务Service] S --> KM[KVMgr
Core/ 四个KV入口] KM --> G[GameLoadGuard
Services/PlayerData] KM --> H[GameSessionHandle
Services/PlayerData] L[登录/加载协调器
Services/] --> G L --> C[LoginContext
私有handle] C --> H PF --> SDK[PlayFab SDK] ``` 目标(第一批只建立依赖方向与交接,不启用正式默认后端): ```mermaid flowchart LR subgraph A[上层:登录、玩法、业务] L[登录/加载/退出编排] B[业务Service与具体动作] end subgraph D[下层:PlayerDataStorage存储模块] G[单一准入门
保留现有guard语义] KM[KVMgr
薄读写/同步入口] H[固定GameSessionHandle] O[Owner/缓存/同步] KM --> G KM --> H --> O end L -->|进入/释放加载门| G L -->|成功Apply后交接原handle;Close时撤销| B B -->|显式传原handle| KM ``` 这里的“存储模块”是逻辑边界。`Services/PlayerData`当前实际含KV存储引擎和加载协调器,不能仅靠目录名判断依赖。图示是长期目标,不是迁移批的文件移动指令。迁移阶段保留`KVMgr.cs/.meta`、现有单一Guard和程序集边界;若迁移后仍有可证实的物理分层问题,再用独立方案审查移动范围与调用影响。 ## 三、Guard引用映射(设计输入,不是改动批准) | 文件 | 现状用途 | 修复边界 | |---|---|---| | `Core/PlayFabMgr.cs` | 11处旧PF加载期禁用/副作用诊断 | 迁移期间保持原结果和计数,最终旧Mgr停用时再清理 | | `Core/KVMgr.cs` | 4处KV读/写/同步准入检查 | 保持四入口返回语义;归属调整后不能反查加载Service | | `Services/PlayerData/PlayerKVGameLoadCoordinator.cs` | 1处进入guard;另持有、检查、关闭租约 | 加载和31模块Apply期间持有,失败/退出正常释放 | | `Services/UserService.KVGameplayLoop.cs` | 2处Editor许可循环进入guard;另持有租约 | 测试循环与正式路径仍互斥,不能当生产Owner路由 | | `Services/PlayerData/PlayerKVSaveRouteEditorValidationHost.cs` | 2处验证guard;另检查4次违规计数 | 保持受审语义和测试覆盖 | ## 四、按依赖排序的修复Todo - [x] **R0 事实与评审裁决**:核审报告、B02封存44/44、Guard20处方法调用/5文件及正式handle缺口;形成本文与两张图。 - [ ] **R1 迁移完整方案**:逐项列PlayFabMgr旧存档成员、当前触发条件、KVMgr/KV现有对应能力、调用方、必要后端差异、固定handle交接/撤销、文件白名单与验收矩阵;复用B01证据。Guard状态、位置、20处引用与四入口方法体保持原样,不在本案规划目录移动或新生命周期抽象。 - [ ] **R2 一次独立方案审查与主会话裁决**:原ZCode按R1完整边界审架构、登录顺序、旧PF禁写、同账号新epoch/Close及最小修改范围。未裁决前不写生产代码。 - [ ] **R3 按方案连续移植**:先完成必要存档入口/原handle交接,再按业务域迁移调用与验证;每检查点更新日志。Guard、物理位置与玩法算法不顺手修改;若某旧方法无法等价承接,标记差异并修订方案审查,不假装改名即完成。 - [ ] **R4 整批验证与复核**:先跑受影响的B02 Route/B01/故障注入、B2加载guard和旧PF并存回归,再用Unity CLI Loop编译与限定合成验证;一次独立实施复核及主会话关闭裁决。不启用真实账号、默认`SaveBackend=kv`或打包。 - [ ] **R5 后续业务批**:以已稳定的同一存储入口迁移核心进度及其奖励,再处理活动/商业/延迟回调;按业务动作归并224候选,每批一份完整方案、一份交付复核,不做逐调用审批。复用旧B02修订1证据,尽量不改计算/UI顺序。 - [ ] **R6 正式接线与收尾**:完成身份/历史账号政策、正式31模块绑定、T08多键部分保存恢复、正常登录/退出及连续玩法组合验收后才切默认KV;令PlayFabMgr运行调用和自动生命周期归零,另验直接SDK依赖并移包。Guard/目录优化如确有必要,迁移稳定后独立设计审查,不作为调用切换的隐含改动。真机/打包仍按用户要求后置。 **下一步实际工作在主会话R1**。第一步产出R1的精确文件白名单及准入/句柄时序图;本文件是复审裁决与修复顺序,尚不是可实施的完整方案。固定地址`http://s101.local:18080/`,使用Unity CLI Loop,不使用UnitySkills,暂不打包。 同日用户明确KVMgr与PlayFabMgr应处同一存档生态位,并询问能否整批替代全部函数、最后处理保护。主会话已将[成员去向和保护分层](M2-管理器同生态位替代策略-2026-09-29.md)作为R1输入:目标是旧Mgr存档运行调用归零,不是原样复制PF合档、生命周期、SDK发送和`null/void/bool`错误语义;最低归属/准入/结果保护须随调用替换生效。