Files
ft/CodexOutput/upserver/阶段4C2拉杆收鱼与奖励保存方案独立审查-2026-09-24.md

47 lines
6.0 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。审查者:ZCode会话。独立性声明:未参与4C2方案编写与实施;此前参与为4C1方案/实施两轮审查。本轮只读+hash重算+源码抽查,未启动Unity/正式网络/许可/消费。
## 受审hash核对
`KVFishingRewardDesign/plan-review-hashes.json`:items **319/319重算全部一致**;plannedAbsent 5项(两个新增源码及meta、KVFishingRewardTests目录)**全部确认不存在**。
## 总判定
**接受。** 方案以最小改动推进真实奖励保存,边界、分段、票据与失败合同完整诚实,且已主动吸收4C1三项教训(首跑退出取消语义、工具强杀规避、LongPress适配)。无P1/P2;P3四条不阻塞。
## 九项逐条回答
**1. 范围:够小且必要。** 7旧文件+2新增是"完整拉杆→结算→奖励→恢复"的最小接线面(每文件对应§2表的一个具体接点);不建通用交易框架(路线2否决正确)、不做无归属全局Flush(路线3否决正确——不能防止重复发奖且无法证明归属)。未见可再缩减而不丢原副作用的替代。
**2. 事件/异步边界:完整。** 本审查直接核实:`PiercingFish(int waitingZone)`入口存在(:524口径)、`OnShow`(:311)中`SetBotCount`(:365)确实早于`Success`(:488)——方案"捕获必须早于SetBotCount"的判断正确;S1(PerfectStrikeCount)/S2(FishEnd至FishingEndEvent)/S3(SetBotCount前至最终保存)三段边界与源码链吻合。分段finally释放collecting、段内无await、ShowUI移出捕获后由可观察Task持有——避免异步资源等待期间混入其他业务 ✓。GuideNext经§3.4"无活动引导"准入+FullCombo引导状态检查+白名单中PiercingToComboB/EternalDeath的await后资格检查覆盖;战斗帧驱动(ControlFishOutWater→IsCaughtFish)有停止推进与过期不设IsCaughtFish条款 ✓。
**3. 鱼记录三态:源码判断准确。** 本审查直接证实`SetGetFishCount`=`fishData[fishId].TotalNum += count`**纯内存无保存**(:998–1003)——"未破纪录收鱼漏存数量"缺口属实;`SetWeight`(:935)仅破纪录保存与方案一致。`SaveCaughtFishForKVLoop`→原`SetFishData`恰补一次保存不加数量、保持原`Map_5_{AreaID}`序列化与卡数据 ✓;首次鱼NewFish默认(CheckFishData先建档)由C2-02覆盖 ✓。
**4. 公式与顺序:保持。** S3顺序表把SaveFishingFrequency/任务/Buff/Guide/SetProficiency/现金事件/AddGold/SetFishWeight/引导通知→最终鱼种→最终主档逐一定序,**主档在全部成就事件后**;SetProficiency正确界定为挑战积分而非通用经验;0现金仍保存次数/鱼种在§6明示;异步展示(Tween/音频/评级)移到确认后只展示已计算结果 ✓。
**5. v3与旧许可边界:清楚。** v1/v2语义原样、v2可显示可拉杆但无新放行;v3恰一消费+一结算;**C1 Continued≠C2奖励完成**明确;取消按RewardConfirmed区分(等待中Fault、完成后仅撤销继续资格——直接吸收4C1首跑教训);重复Panel/FishEnd须原进程动作绑定非各自bool ✓。
**6. 票据诚实:完备且比4C1更严。** 奖励动作自有封存记录、不混入已完成消费票据;每key最终原票据Confirmed+同动作同key跨段(S1↔S3)合法替代;**段外实际变值写经outside-segment采样拒绝验收**(即使后被S3覆盖也不掩盖)——比4C1更严;最后localOnly拒绝、Unknown/401/部分提交不退款不补发不冒充;"已扣费或部分写成功但未呈现奖励"的失败如实允许记录、不称原子 ✓。
**7. §3准入:具体、可执行、保守。** 19条GetFishCount分级(3条活跃Type1须频次≥3+解锁就绪;30200350–65须真实服务时间过EndTime≥120秒且校验条件/时段/分支字段而非仅ID)✓;引导/巡游(GetFishSwimToMap==0)/挑战(State 0/3或时间不允许)/收集/礼包/对战Item全部只读预检、无法可靠读取即拒绝 ✓;活动Open/Close观察不记通过 ✓;"这些是可执行边界不是已通过声明"的定位诚实。
**8. 数据矩阵与真实验收:足以证明奖励保存。** §6矩阵到字段级(19槽仅消费/奖励项、goldRM不增、Map键仅目标鱼、任务键仅实际变更者、预期不变键清单);本期必须**新消费一次**且上次鱼不可恢复(诚实);C3c明确规避已知会超时强杀的`uloop launch --quit`并要求已核实的无强杀关闭路径、无法满足则保持验收未完成 ✓;C3d新进程新缓存恢复对账、自然时间变化按旧公式解释 ✓。
**9. 可批准按§9检查点实施:可以。** C0–C4顺序合同完整(红测先行、准入全过才发v3许可、失败不自动二次付费)。
## P3清单(不阻塞)
- **P3-1**:C2-12"目标鱼数量最大重量"读回断言建议同时校验`Map_5_{AreaID}`中**其他鱼与卡数据字节不变**(§6已列"其他鱼保持",落为显式逐键断言更利于对账工具自动化)。
- **P3-2**:S3段内"原OnShow引导通知"在无引导准入下预期无操作——若运行中意外触发引导开启即终止已覆盖;建议事件流记录该通知调用次数(预期0相关)作辅助证据。
- **P3-3**:`SaveCaughtFishForKVLoop`要求"数据已存在"——建议实现时断言`fishData.ContainsKey`且TotalNum已含本次增量(与S3前值快照比对),防止空档误保存。
- **P3-4**:C3b的LongPress 0.15秒适配沿用4C1已验证参数——建议把该参数与UIButton阈值校验写入固定操作脚本(4C1 P3-1的延续)。
## 保留项
本期通过≠完整捕鱼系统/4C整体/热换号/G4/普通用户开放;自然失败不计成功;P2-α、身份、tickets、4D、最终打包不变。方案自述"未编码、未运行测试、未启用许可、未发生新消费"与本审查观察一致。
## 结论
**接受4C2方案,批准按§9检查点实施(主会话逐条裁决后)。** 建议P3四条随裁决采纳为实施说明。