Files
ft/CodexOutput/upserver/阶段4B1独立实施复核-2026-09-23.md

64 lines
6.4 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.
# 阶段4B1独立实施复核
日期:2026-09-23。复核者:用户指定外部AI(ZCode会话)。范围:4B1实施(`PlayerKVLoginContext.cs`+`PlayerKVLoginPrepareResult.cs`+`KVLoginContextTests`)的只读代码审查+证据核验+独立复跑。本轮未修改任何生产/测试代码、csproj、共享文档或原报告;未使用子Agent;未访问正式服;未运行KVLiveTests或3C --live-s101。
## 受审版本(SHA256,本复核逐项重算)
| 文件 | SHA256 |
|---|---|
| PlayerKVLoginContext.cs | `7552C331BCD7B5B51A9726085D25319E9D77653E5519EE76D7772EEB4B757A29`(与提示词一致) |
| PlayerKVLoginPrepareResult.cs | `108CA361C7153D19A08CD348B8325538019A86C426BDD80B907528399F22B290`(与提示词一致) |
`scope-hash-check.json`68项既有源码/meta/测试Program/csproj——本复核重算**全部unchanged**(UserService/PlayFabMgr/DataCenter/Stages/4A/3A/3B/账户源码零改动)。历史失败run(21组/1失败)与中间run均保留未覆盖;最终run `20260923084050…`23组/274断言/0失败。
## 复核结论
**接受4B1实施。无P1/P2。** 建议主会话逐条裁决后关闭4B1;4B2/4B3仍需各自独立方案与评审,本报告不自动授权。
## 代码审查(静态推导+实测)
**PlayerKVLoginContext:通过。** 逐项:
1. **单次Prepare/首token(P3-A/P3-C裁决落实)**:`preparation`单TCS;重复调用返回**原任务引用**;不同token仅`differentTokenCount`诊断+Debug.WriteLine,不替换生命期、不Assert不抛(行75–94)。Close后再次Prepare仍返回历史任务(可能是历史Prepared成功),符合P3-A裁决的"历史Task语义";仅Close先于首次Prepare时返回Cancelled(行92)。
2. **workSettled与对外结果分离(§4.3)**:`PrepareCoreAsync`的finally**无条件**先完成workSettled(行173),随后才走`CompleteFailureAsync`→await CloseAsync→发布失败结果(行214–226);CloseCoreAsync只await workSettled与Bridge.Close,**从不等待对外Prepare任务**——互等环在结构上不存在(B1-10实测无循环等待)。
3. **Close语义**:锁内`revoked=1`+创建closing TCS(返回Task前同步撤销✓);重复Close同任务;close-before-Prepare时workSettled立即完成(行237)→后续Prepare零请求Cancelled(B1-11实测)。Close经`Task.Run`执行,取消注册回调不内联执行清理(行239–243注释及实现);faulted任务经ContinueWith观察,无未观察异常。
4. **资源次序(§4.4)**:`lifetime.Cancel→await workSettled→await bridge.CloseAsync→session.Dispose→registration.Dispose→lifetime.Dispose`;**Bridge Close失败时session不Dispose**、引用与faulted任务保留(行255–257注释及实现,B1-12实测);`lifetime.Cancel`自身异常延迟上抛为CloseFailed。
5. **认证→Get→快照顺序**:session工厂返回后校验`ApiBaseUri==api`;登录→epoch复查→Bridge.OpenAsync(同一session、固定根/epoch、`EpochCurrent`委托、context CTS)→`ReadLocalSnapshot`→发布前锁内复查revoked(行149–161)。Stale/NotReady区分保留,SyncStatus证据保留。
6. **外部委托**:`EpochCurrent`在无context锁状态下调用外部回调(行191–201);异常记录类型并自动触发CloseAsync→Unexpected;同号重登靠Cookie引用失配判定(IsCurrent的ReferenceEquals)。
7. **IsCurrent**:未Prepared恒false;Close后revoked=1恒false;历史快照仍在结果对象中可枚举但不授权(P3-A)——B1-11-P3A专项用例实测。
8. **无越界**:文件无Unity/PlayFab/GContext/业务初始化/写接口引用;公开构造固定`DefaultApiUrl`;internal工厂不外泄session/handle/传输。
**PlayerKVLoginPrepareResult:通过。** 成功路径对快照再深拷贝为ReadOnlyDictionary(与4A快照双保险脱钩);失败Data=null;`OriginalError`/`CleanupExceptionType`/各阶段可空错误字段完整;XML注释落实P3-B(失败/取消等待真实收尾、忽略取消可长期挂起、以CloseAsync为准)。
**P3-A/B/C裁决落实核对:全部落实**(A=历史任务语义+B1-11-P3A用例;B=两处XML注释;C=诊断计数+Debug.WriteLine,无Assert)。
## 独立复跑证据(本会话自有,真实退出码)
| 命令 | 结果 | 退出码 |
|---|---|---|
| KVLoginContextTests | 23组/278断言/0失败(新run `20260923090458_327462ec…`) | 0 |
| KVGameBridgeTests(4A) | 18组/226断言/0失败 | 0 |
| KVContractTests(阶段2) | 42/42 | 0 |
| KVSyncTests(3A) | 86/86 | 0 |
| KVSyncCoordinatorTests(3B) | 29/29 | 0 |
| KVSyncCoordinatorReviewTests | 通过 | 0 |
| KVStage3CTests --offline | 8/8 | 0 |
| KVLiveTests仅build | 0错误 | 0 |
| uloop compile --force-recompile + get-logs | 错误0条(证据:`KVLoginContextTests/unity-compile-review.json`/`unity-errors-review.json`) | 0 |
本复跑未再现KVSyncTests偶发失败(86/86,退出码0);按4A关闭裁决口径,P3-1根因仍为未定,不以本轮通过宣称已消失。
## B1-01~B1-16逐行核对
交付矩阵§4的23个用例与最终run的test名/断言数逐项对应(含B1-04拆三组、B1-09拆两组、B1-11含P3-A专项与49断言并发组、B1-12拆三组、B1-13拆两组);未发现矩阵与证据不符。"通过"均为合成替身下的技术验证,与交付口径一致。
## 非阻塞观察(P3,仅记录)
1. **P3-1'|`IsCurrent`对`session`的非阻塞读取依赖prepared发布顺序。** `Volatile.Write(prepared)`与字段写入的顺序经volatile读语义保障正确(acquire),实现无缺陷;仅提示后续若增字段需维持"先写字段后写prepared"约定。位置:PlayerKVLoginContext.cs行54–63/152–159。
2. **P3-2'|`CompleteFailureAsync`在CloseFailed时仍保留原始错误。** 已按合同实现(OriginalError);建议4B2接线文档显式引导调用方同时检查`CleanupFailed`与`OriginalError`,避免只看Error==CloseFailed丢失根因。文档级建议。
3. **P3-3'|首次失败run的夹具缺陷记录。** 首轮21/1失败系测试夹具token注册错误(自审已记录),非生产缺陷;历史run保留正确。无行动项。
## 结论
**接受4B1实施;无P1/P2;P3三条仅记录。** 建议主会话逐条裁决后关闭4B1。4B2(游戏加载与内存隔离)需独立完整方案(业务档校验、空档阻塞策略、初始化副作用、OnInitData时序、401/退出接线)与评审后实施;4B1关闭不放行游戏接线或正式业务KV。