Files
ft/CodexOutput/upserver/阶段4R1复验裁决与后续最小范围-2026-09-24.md

64 lines
6.6 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.
# R1复验裁决与后续最小范围
日期:2026-09-24。主会话。当前交付:复验逐项裁决、后续源码核查和范围建议;不是后续编码批准。
## 检查点0:复验裁决
《阶段4R1关闭复验-2026-09-24.md》SHA256:`2D2D3CDA2B51C89B55EA0ADB7CD3D472A2824398153034CE8D3DB0D94FA7EBD5`。
主会话在更新状态文档前重算`KVGameplayLoopTests/repair-final-hashes.json`:56/56一致,0缺失、0差异。
| 复验项 | 主会话裁决 |
|---|---|
| P2-1建筑默认值 | 接受;缺键0、已有字符串/显式null/Reset边界保持;无需再次改代码 |
| 退出衔接 | 接受;仅Editor KV模式,Ready才Stop,其他状态不重进;保留审批来源区别 |
| 56项hash | 主会话重算一致,接受受审版本 |
| 红测先行 | 接受既有首败记录,不覆盖、不为本轮文档确认重复制造失败 |
| 独立复跑4B2/B3A | 接受75组1716及13组544;三个条件探针证据沿用修复交付,不把单次运行当三次 |
| 第三进程真实回归 | 接受建筑0、正常关闭及非运行状态证据,不把CLI await超时解释成关闭失败 |
| 服务器对账 | 接受101仍空、102仍45键且逐值一致;不再导入或补写 |
| 工具限制 | 保留跨Stop等待超时和Unknown tool记录,不删除或美化 |
| 关闭范围/备注 | 接受;R1关闭有效、无新P1/P2,不重开R1复审;后续仍需独立方案和裁决 |
本次复验没有新的代码修订要求。旧修复清单保留为历史受审版本;随后状态文档变化属于本次检查点,不回写旧hash清单。
## 检查点1:下一步的实际阻塞
沿用用户“真实游戏先跑起来、单账号重启式重登、最少改逻辑”的要求。候选优先级为**4C1普通钓鱼的一次消费保存确认**,不默认启动全B/C热换号或转盘改造。已向用户提供范围选择,尚未收到新选择时按此候选继续设计准备,不视为消费方案已经批准。
源码事实:
1. `PlayFabMgr.SyncDataImmidiate`(323行起)在KV模式明确终止run;全项目直接业务调用仅捕鱼和转盘两处。不能为了让捕鱼运行而全局改成true或开放另一个未经处理的调用方。
2. `FishingBehaviorB.DoConsumeBait`(744行起)先启动async void的ConsumeBaitOnPlayfab,立即调用WaitForFishBiteED;后者开启后续玩法/拉杆按钮,未等待保存结果。接收bool也只写日志。
3. `ConsumeBaitOnPlayfab`(769行起)先复制扣费前的PlayerDataDic,再只改副本的`energy`别名;同时ReduceEnergy修改实际内存。若副本已有newData且费用大于0,则newData第4槽仍是旧体力,energy是扣后体力。当前Schema.DecodeCore(290、318行附近)明确将二者不等判为ConflictingRepresentations。这里是源码推导,未实际发送该数据。
4. `ReduceEnergy`→`SetEnergy`会累计energyRM、发布PlayerData并保存;从满体力降到阈值下还会启动RecoveryEnergy,再次写入恢复时间和整档。故不能把扣体力当作一条无副作用赋值,也不能简单加一次“最后写入票据”就声称所有原写都已确认。
5. `ConditionType.ConsumeEnergy`有成就、战令、MiniBP、LuckyTask等订阅。具体本次场景哪些订阅激活、哪些键会写入尚须逐条核实;当前不宣称全链已盘点完成。
6. 转盘旧协程的等待只走一次便break,ConsumeOnPlayfab不论bool真假都设isDataSynced=true。它需要自己的失败合同,本次不得因共享保存入口变化被连带开放。
## 三条路线与建议
| 路线 | 收益与成本 | 结论 |
|---|---|---|
| 先完成全B/C跨账号隔离 | 覆盖全面,但扩大大量回调和共享对象改动;不是当前单账号运行所必需 | 后置 |
| 先改完整退出自动保存 | 能处理普通未确认记录,但不能解决消费后立即继续玩法及旧副本冲突 | 独立后续项 |
| 先做普通钓鱼消费确认 | 直接推进可玩的普通玩法;保留单账号限制,聚焦扣费、确认和继续时机 | 推荐 |
## 后续完整方案必须定下的合同
以下是设计验收清单,不是已完成实施设计,不凭本材料直接编码:
- **唯一动作入口**:首次扣费前固定原会话和本次动作;重复点击/协程/动画回调不得二次扣费。免费、重试、特殊鱼走向逐一界定,不能仅改收费支路就声称全普通钓鱼通过。
- **唯一有效存档表达**:复用PlayerData现有整档序列化,不继续发送“旧newData+新energy”的副本;保留其余玩家字段,不放宽Schema来容忍矛盾。
- **副作用与原票据**:列明ReduceEnergy、恢复计时、PlayerData通知及消费事件的同步/异步写;明确哪些票据属于本动作,如何处理同键替代,不能从全局最后票据推定。
- **继续条件**:持有原票据确认且动作/对象仍有效后,才允许调用一次WaitForFishBiteED。Accepted不是Confirmed;Unknown、401、关闭、StorageError和取消不能转换成可重扣的false。
- **失败语义**:保留不确定结果,不自动回滚、重扣或领奖;明确已扣款但未继续玩法时的表现。此处涉及用户体验与恢复范围,不能把原R1停止run合同直接等同于完成消费事务。
- **明确非原子范围**:扣费和后续鱼获/任务奖励不是天然原子事务。完整收鱼奖励链未经核查前,不能承诺一次完整捕鱼闭环或普通用户正式启用。
- **测试与真实运行分开**:先用合成后端覆盖确认前不继续、重复回调、写后丢响应、同键替代、关闭与恢复计时竞争。再列真实102现有档的备份、允许变化key、一次动作和重登对账;不重导45键,不用101空档造数据过关。
候选代码范围仅`FishingBehaviorB.cs`对应消费链、`DataCenter.PlayerData.cs`复用序列化/消费方法、`UserService.KVGameplayLoop.cs`必要的固定动作确认及固定验证入口;是否需要修改共享PlayFabMgr、许可字段或其他订阅者,必须由上述调用链证据决定。现在没有对这些文件的编码批准,也不另造Owner、缓存、传输或通用事务框架。
## 下一检查点及责任
主会话:完成消费事件及恢复计时写入矩阵、原动作身份与错误合同、精确方法白名单、测试矩阵,形成完整4C1方案。独立评审侧:收到完整方案后评审;主会话核hash逐条裁决后才编码。**当前无需评审者重复审R1,也不能把本次关闭复验当成4C1实施批准。**
本轮没有改游戏代码、没有启动Unity、没有发正式服务器请求。固定http://s101.local:18080/;Unity CLI Loop、不用UnitySkills、暂不打包。