Files
ft/CodexOutput/upserver/B3BatchMigration/M2/M2-C3a验证边界与执行记录-2026-09-30.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

51 lines
5.7 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.
# C3a 离线验证执行边界与裁决
用户要求继续验证。本检查点不修改生产源码、原测试源码、原断言、配置或旧C2d交付清单,不开启Play、正式请求、付费或打包。沿用已审C3离线验证范围,补完整加载、原装备与退出回调兼容检查及静态真实集成缺口核对。
旧ExitRegression工程只有QuitAct和旧stub,漏掉合批已新增的IKVUserLifecycle接口,首次编译失败。完整核对结论:属于测试编译输入过时,不是Unity源码编译失败。仅用独立MSBuild targets临时加入现有真实IKVUserLifecycle.cs;其PlayerKVGameLoadError类型从当前源码精确提取原enum作为编译壳,不复制Coordinator行为、不声明新增关闭断言。原测试实际验证OnStarted在loop启用/禁用与五种关闭状态下的分支、原清理和返回PreBoot约束;不把它说成真实StartAsync/网络关闭全链验证。
该临时targets和enum只位于CodexOutput,作为测试运行辅助输入,无生产可达性;无需扩大生产白名单,也不改旧ExitRegression项目文件。记录输入hash并明确证据限制。原测试任何失败不修改生产语义来凑通过。
## 非Editor工厂探针编译输入核对
原PlayerProbe排除Program.cs,但合批新增两个M2测试partial仍被编译,引用被排除Program中的Check/Handler等导致失败。仅在本次PlayerProbe构建中追加targets,排除这两个依赖Editor测试驱动的partial,保留原FactoryProbe所有检查、所有生产源与Stubs。正常/ANDROID+AGG宿主仍执行原M2测试,不删断言或给生产增条件编译。此为临时编译输入隔离,不是实际Unity Player构建,也不改变旧工程。
## 本轮结果
| 验证 | 实测结果 | 证明范围 |
|---|---|---|
| KVGameLoadTests | 90组、2006断言、failed=0,进程退出0 | 离线加载、Guard、回滚、31模块合同、会话及关闭边界;断言计数变化不当新增覆盖 |
| CLI equipment-chain | 9组、28断言,formalRequests=0、restored=true | 原装备链及仍使用的旧验证入口 |
| 实际QuitAct/原ExitRegression | 临时补当前契约输入后10组、35断言、0失败、requests=0 | OnStarted退出分支和五种关闭状态;不是StartAsync真实关闭全链 |
| 非EditorFactoryProbe | 两类验证能力工厂不可用检查通过 | 合成编译条件;不代表Unity Player编译或打包 |
| C2d受审组合 | 2177项及20项证据hash全部一致 | 生产代码、旧测试代码和C2d证据没有被本轮改动 |
| 退出现场 | playing/enabled/ready/permitExists均false | 未进入Play,未打开真实运行许可 |
旧退出工程原命令缺IKVUserLifecycle、原PlayerProbe混入依赖已排除Program的两个测试partial,首次编译失败日志保留。两项均通过独立targets调整本次编译输入后运行;原工程直接运行仍需这些补充参数。没有把失败日志删除或把临时编译输入当成工程本身已修复。
复跑命令:
```powershell
dotnet run --project CodexOutput/upserver/KVGameLoadTests/KVGameLoadTests.csproj --no-restore
uloop execute-dynamic-code --project-path C:/projects/ft/Client --code 'return await KVGameplayLoopSetup.RunValidationAsync("equipment-chain");'
dotnet run --project CodexOutput/upserver/KVGameplayLoopTests/ExitRegression/ExitRegression.csproj --no-restore '-p:CustomAfterMicrosoftCommonTargets=C:/projects/ft/CodexOutput/upserver/B3BatchMigration/M2/M2-C3a-ExitInputs.targets'
dotnet run --project CodexOutput/upserver/KVGameLoadTests/ServiceHost/ServiceHost.csproj --no-restore -p:PlayerProbe=true '-p:CustomAfterMicrosoftCommonTargets=C:/projects/ft/CodexOutput/upserver/B3BatchMigration/M2/M2-C3a-FactoryInputs.targets'
```
## 首场景仍不可放开的具体调用链
以下是当前源码静态证据,不是运行抓包:
1. `Stages/FishingStage.cs:249`调用`LeadboardData.SetLvData`;`DataCenter/DataCenter.LeadboardData.cs:205`调用`SetLeadboardData`,其`:169`仍调用`PlayFabClientAsyncAPI.UpdatePlayerStatisticsAsync`。榜单读取`:186`仍用`GetLeaderboardAsync`。因此不能声称首场景PF调用计数为0。
2. `Stages/FishingAct.cs:267`在普通首场景分支调用`FriendService.GetFriendData`;`Services/FriendService.cs:36`再调用`GetFriendList`,`:145`仍用`PlayFabClientAsyncAPI.GetFriendsListAsync`。只迁个人KV存档不能证明好友关系读取已替代。
3. `Services/KVUserService.cs:282/288`只读取本人或已有公开资料缓存,缺失他人等级会失败、资料返回null;他人资料远程读取能力仍未接通。`Duel/UI/EventFishingDuelPanel.cs:612`也仍明确提示KV匹配未接通。
4. `Stages/LoginStage.cs:126`与`Stages/PFLoginAct.cs:99-114`现有两闸继续保留;不通过跳过排行榜、好友或匹配来伪造迁移完成。
这些属于既有集中问题单的四项外部能力缺口,并非重新要求确认ID或邮件协议。继续实施需要服务端开发侧给出现有KV等级榜聚合、公开资料、好友关系和匹配能力的最小调用方式;本Agent不读改服务器源码,不猜测路由。客户端原游戏服请求及已迁个人KV存储保持原逻辑。
## 下一步与边界
本轮可执行的补充离线验证已完成,C3真实首场景、真实Player/SignalR、正式账号保存及新进程恢复仍未验。现有审查明确要求首场景PF调用计数=0且全链就绪后才同时解除两闸,上述实际代码尚不满足;不能仅为继续验证而进入正式场景或改变业务。
C2d生产交付hash继续有效。本轮只新增验证材料、临时编译输入和日志,不另发逐项送审;最终整批实施复核仍保留。无正式请求、服务器代码操作、Play、付费或打包。