Files
ft/CodexOutput/upserver/阶段4C2收线取消缺陷最小修复方案-待评审-2026-09-24.md

53 lines
4.3 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.
# 阶段4C2收线取消缺陷最小修复方案(待完整评审)
2026-09-24。依据:《阶段4C2第二次真实尝试与收线取消记录-2026-09-24.md》及用户提供的完整错误堆栈。仅修复已实证缺陷,不放宽任何准入/技能检查/票据保护;未编码。
## 缺陷与证据
用户真实收线完成时(FishEnd 已触发)报错堆栈:
```
PlayerKVGameplayLoop:Fault ← CancelReward ← FishingUpdateSys:OnDisable(FishingUpdateSys.cs:3203)
← UnityEngine.Object:Destroy ← UIManager:DestroyUI(UIManager.cs:938)
← FishingUpdateSys:FishEndCore(:1312) ← FishEnd(:1255) ← Update(:1227)
```
正常完成链为 `FishEnd → BeginRewardEnding(置a.Ending=true) → using BeginRewardSegment("ending") FishEndCore() → ShowKVRewardPanelAsync(等待票据确认后展示)`。`FishEndCore` 内 `UIManager.Instance.DestroyUI(UITypes.FishingPanel)`(:1311)会销毁承载 FishingUpdateSys 的战斗面板,同步触发 `OnDisable/OnDestroy` → `CancelReward(this,...)`。`CancelReward`(UserService.KVFishingReward.cs:281-288)只校验 actor 身份,不区分该拆除是否属于完成路径自身:`a.Cancelled=true` 且此刻 `Ready && !a.Confirmed` → Fault("Fishing reward cancelled: controller disabled"),奖励在确认前被自己的收尾拆除取消。第二次真实尝试(run 62216)即此:门通过、扣费票据确认、战斗约18秒正常结束,随后被误取消退出,无奖励。
## 拟改动1(生产,唯一行为变化):UserService.KVFishingReward.cs CancelReward 增加一行守卫
在现有 actor 身份守卫之后、`a.Cancelled=true` 之前增加:
```csharp
if(a.Ending && !a.Confirmed && ReferenceEquals(actor,a.Controller)) return;
```
语义:**已进入完成流程(Ending=true)且尚未票据确认(!Confirmed)时,控制器(Controller)自身的 disable/destroy 属于 FishEndCore 的正常拆除窗口,不构成放弃。**
- 战斗中(Ending=false)控制器被禁用/销毁:仍按原逻辑取消并 Fault(真实放弃保护保留)。
- 票据确认之后控制器 disable:守卫不适用(Confirmed=true),保持原语义——置 Cancelled、不 Fault(既有固定验证用例"confirmed-normal-cancel-no-second-exit"期望不变)。
- Panel 与 Consumption.Actor 两个 actor 路径完全不变;合法放弃主通道 `CancelFishing→CancelReward(action.Actor)`(KVGameplayLoop.cs:195)不受影响。
- 若该窗口内票据确认本身失败,仍由 ConfirmRewardAsync 的既有 Stop/Fault 报错,不产生悬空奖励。
不新增字段、事件、日志框架、await;不动 CheckRewardContext、技能检查、准入、票据等待、Fault 通道。
## 拟改动2(既有固定验证维护):UserService.KVFishingRewardValidation.cs 增加一组用例
新增组(命名如 `ending-teardown-pre-confirm-not-cancel`):构造 rewardAction → `BeginRewardEnding` 成功后、`ConfirmRewardAsync` 完成前,模拟控制器 disable(调用 `CancelReward(rewardAction.Controller,"controller disabled")`)→ 断言 `!rewardAction.Cancelled && Ready`(红:现状会 Cancelled+Fault);随后正常完成确认与展示,断言流程可走完。既有"confirmed-normal-cancel-no-second-exit"用例保持原样(验证确认后语义未变)。
## 验收
1. 固定验证全量重跑:既有43组168断言+新增组全部通过(Unity空闲Editor执行 `KVGameplayLoopSetup.RunValidationAsync("fishing-reward")`)。
2. Editor编译0错误、SERVICE_HOST编译exit0。
3. 静态diff判据:生产源码仅 UserService.KVFishingReward.cs 一行守卫+Validation文件新增用例段;FishingUpdateSys.cs、FishingRewardPanel.cs、KVGameplayLoop.cs 等其余文件字节不变。
4. 修复后真实收鱼闭环仍需用户另行授权新进程运行;本修复不构成4C2关闭。
## 请独立评审裁决
1. 守卫条件 `Ending && !Confirmed && actor==Controller` 是否精确覆盖且仅覆盖误取消窗口?有无遗漏的取消场景(如FishEnd开始后用户真实退出应如何表现——应经CancelFishing/退出排水路径)?
2. 确认后语义不变的论证是否成立(对照既有验证用例)?
3. 新增验证用例设计是否充分(红绿边界)?
4. 是否批准这两处限定修改?
请输出问题等级(P1/P2/P3)、可执行修订与明确允许/不允许实施结论。