Files
ft/CodexOutput/upserver/B3BatchMigration/M2/M2-先移植后优化独立方案审查-修订1.md
Liubing\LB 6813da149a feat(upserver): 保存M2客户端KV迁移至本人统计写检查点
保存独立KV用户服务、固定会话存档与原业务接线,以及C3d资料缓存和C3e本人统计写。
保留原PF/AGG路线、业务公式和时序;榜单读取、好友资料、公告、匹配及首场景闸仍待完成。

验证:ServiceHost两条件各33组646断言;Unity CLI Loop编译0错误269警告。
包含相关方案、评审裁决、测试及状态文档。未操作服务器、正式账号或打包。
2026-09-30 19:19:05 +08:00

88 lines
6.1 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.
# M2先移植后优化完整方案(修订1)独立方案审查
日期:2026-09-29。审查者:ZCode会话(M2纠偏意见审查者、B02全链审查者)。本轮只读+hash重算+源码核对;未修改任何生产/测试源码/共享文档。
## 受审hash核对
`M2-先移植后优化受审基线-修订1.json`:**15/15重算全部一致**。
## 总裁决
| 裁决对象 | 结论 |
|---|---|
| **总体路线(先移植后优化)** | **通过** |
| **CP1–CP2首批可实施范围** | **有条件通过**——CP1签名/白名单需补具体条目后方可编码 |
无P1;P2一条;P3三条。
## 重点逐项裁决
### 1. 历史事实:Guard为迁移新增——**确认**
本审查独立核证:`git show f40a816cc:Client/Assets/Scripts/Core/PlayFabMgr.cs | grep -c Guard`=**0**(旧树无Guard);Guard文件由`0eb43b2b4`(9月28日upserver迁移提交)引入。**Guard不是旧PF固有语义,是迁移期行为兼容保护。**
方案正确处理:迁移期保留Guard类/检查/计数→迁移完成后(CP5)据证据独立评估是否删减。**不与当前批混做**——这是对我此前"纠偏意见"中"guard下沉"建议的正确修正(用户纠偏后撤回),分层优化留独立阶段。
### 2. 关键时序:验证路径仍持Guard vs 正式路径释放后发布——**方向正确,需补实现细节**
源码核实:
- `PlayerKVGameLoadCoordinator`::90 `TryEnter`获取Guard→Apply→**Close时才Dispose**(:186)——整个受控加载生命周期Guard在线→四KVMgr入口全程拒绝——**验证路径行为正确保持**;
- `UserService.KVGameplayLoop`(Editor限定玩法)::568 `TryEnter`获取→:574 **Apply成功后立即Dispose**→发布固定handle→KVMgr入口可用——**Editor路径已验证"释放后发布"时序**。
方案§2提出:正式路径=Prepare→Decode→31模块Apply→通知→**释放Guard→发布原handle**;失败→Revoke/Close不发布。这一时序与Editor已验证路径一致,**合理且可最小实现**(关键:正式入口区分验证模式,成功Apply后走释放分支,不复制加载算法)。
**P2-1**:方案声明"若这套分流必须大量复制现有验证代码,审查应判定需要重做本节"——本审查评估:当前Coordinator的LoadAsync约200行,正式入口若按"模式参数"区分(验证/正式),在成功路径末尾加条件释放Guard并发布handle,预计**增量约30–50行**而非大量复制——**可接受,但CP1必须给出具体签名与差异行号**。
### 3. 正式句柄交接——**方案正确识别为CP1核心**
`PlayerKVLoginContext`的handle为私有(我此前已核实);`PlayerKVAccountLease`是网络租约不是存档句柄(方案明确区分)。CP1的正式出口=受控按身份/epoch/关闭状态从Context给出原handle——方向正确。具体交接签名(internal方法/属性/回调)需在CP1补全。
### 4. 旧成员逐项承接(§3)——**完整且差异明确**
| 旧成员 | 承接 | 判断 |
|---|---|---|
| GetLocalData→ReadKV三态 | 正确——B01已验证 |
| UpdateUserDataValue→WriteKV Accepted/Confirmed分离 | 正确——B01+4C已验证 |
| SyncDataImmidiate→原票据观察 | 正确——4C1合同 |
| CompareDatas→ Prepare/Decode/Apply | 正确——4B2已关闭 |
| 40秒循环→现有KV Owner同步+正式触发 | 正确——先保留旧路径 |
| Awake/生命周期→CP4停用 | 正确——以证据为准 |
**"不能同一动作混用两个后端写同一档"**——关键红线,防止双写。
### 5. CP1–CP2首批可编码性——**尚不充分(条件通过理由)**
方案§5列出了候选文件(KVMgr/LoginContext/Coordinator/Capability/Bindings/UserService.KVLoad/UserService+B01最小改动),但:
- CP1的具体签名(正式入口方法名/参数/Guard释放调用点/句柄出口签名)未列;
- CP2的B01文件"确有正式接线需要的最小改动"未定行号;
- 正式工厂与验证工厂隔离的具体机制未描述。
**这些不是方案缺陷而是CP0→CP1的过渡产物**——方案自身声明"CP1精确签名…必须由独立审查裁决为充分"。
### 6. 最小改动检查——**无越界**
无Guard本体修改、无目录移动、无第二套缓存/队列、无PF SDK代码塞入KVMgr、无全局当前handle、无无证据玩法逻辑改动。Guard/KVMgr归位留CP5独立——**正确分离**。
### 7. 验收矩阵V01–V06——**覆盖充分**
V01(Guard时序+验证路径保持)、V02(旧handle/epoch)、V03(三态不混淆)、V04(消费票据+T08前置)、V05(全量回归+三条件编译)、V06(默认切换前置+合成transport)。停止条件明确。
## P2/P3清单
**P2-1**:CP1须补全的具体条目(编码前置条件,非方案缺陷):
1. 正式加载入口的方法签名(含模式区分参数或独立方法)
2. Guard释放的精确调用位置(Apply成功后的哪一行之后)
3. 原handle从LoginContext交接的具体签名(internal属性/方法)
4. Player构建31模块绑定的可用性方案(当前Bindings受UNITY_EDITOR限定,Player不可用)
5. 正式工厂配置来源(非Editor许可路径)
**P3-1**:建议CP1补全时同时产出**Guard引用映射表**(此前纠偏审查建议——21处引用的文件/用途/是否随CP5评估),作为CP5的输入数据。
**P3-2**:§3的`InitBuffer`行——"对照现有KV Owner的缓存/同步行为和正式运行触发"——建议CP3各域迁移时记录实际发现的差异(当前只有旧PF行为描述),使CP4停用旧组件时有核对依据。
**P3-3**:V05的"Player目标条件编译"——当前默认非Editor存在历史`_cheatingScore`编译错误(挂账项);建议V05明确"Player编译须在历史错误修复后或以已知错误白名单形式通过",不因历史问题阻塞CP1–CP2。
## 结论
**总体路线通过。CP1–CP2有条件通过——主会话需补全P2-1的5项具体条目(建议以CP1附录形式补入方案或另出一份CP1细化文档),经主会话裁决后即可进入CP1实施。** 后续81文件/三个业务域(CP3)不因本稿通过自动获批——方案自身声明一致。