Files
ft/CodexOutput/upserver/阶段4A交付与验收矩阵-2026-09-23.md

83 lines
8.1 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.
# 阶段4A交付与验收矩阵
日期:2026-09-23。最新状态:**外部实施复核已完成,主会话核对版本并逐条裁决,4A限定阶段关闭;4B仅方案准备、未编码。** 见[独立复核](阶段4A独立实施复核-2026-09-23.md)及[关闭裁决](阶段4A实施复核裁决与关闭-2026-09-23.md)。下列测试是原交付记录;独立复跑和P3保留项以关闭裁决为准。
设计及补审放行依据:《阶段4A差异裁决与实施批准-2026-09-23.md》。所有4A网络测试均为替身;没有访问正式服、没有打包。
## 1. 本阶段可观察效果
- Owner可读取当前Ready会话的独立不可变本地合并快照;未Ready不会被包装成空存档,过期/关闭优先返回StaleOrClosing。
- 桥接只拥有KV Owner,不销毁登录session。固定句柄永远指向原Owner,旧回调不会借用新账号。
- Open/Close按任务链串行;Close立即撤销入口、等待旧传输与Owner关闭完成后才允许新Owner;排队取消不提前放开屏障。
- 正常初始Get失败后可重新Open;Close失败保留任务与Owner并阻止重开。Unknown不自动重试,Close不隐式Flush。
- 这些是独立层能力。游戏仍未接入这个桥接,不能据此称玩法存档已经迁移。
## 2. 文件和完整SHA256
| 文件 | SHA256 |
|---|---|
| PlayerKVSessionOwner.cs | BFB5AC0DF38BCACC341646292ACAA71606F2DC5FECF91535785D222EAFACF7B5 |
| PlayerKVLocalReadResult.cs | 9A00AA0ECEA286FC4474729A1BFABDD3D5A1453182B5FCB91D11CD81724481AF |
| PlayerKVGameSessionBridge.cs | DD888351BFA4BBA03E953F39E11362AF8EA9F76FB56AC1CB77D9053C81227363 |
生产路径均为Client/Assets/Scripts/Services/PlayerData。
新增两份meta;三份旧csproj各新增一行Compile;新增KVGameBridgeTests宿主和证据。
所有10个新增/修改源码、meta、csproj的完整hash见[final-source-hashes.json](KVGameBridgeTests/final-source-hashes.json)。
边界证据:
- [owner-diff-check.json](KVGameBridgeTests/owner-diff-check.json):去除新增读接口及辅助后,Owner原文件hash完全匹配。
- [project-diff-check.json](KVGameBridgeTests/project-diff-check.json):三个旧csproj各只有已审一行Compile新增。
- [scope-hash-check.json](KVGameBridgeTests/scope-hash-check.json):其他7份基线生产文件、3C测试Program及既有3B/Review Program未变。3C历史证据未改;其旧源码hash仍表示当时版本,4A新增接口记录在本阶段。
## 3. 命令与运行结果
命令工作目录C:/projects/ft;使用已有离线依赖。新宿主首次restore受沙箱NuGet配置读取限制,提权读取后成功。测试期间无正式网络请求。
| 命令 | 结果 | 证据(KVGameBridgeTests/) |
|---|---|---|
| dotnet run --no-restore --project CodexOutput/upserver/KVGameBridgeTests | 退出0,18组,测试断言221+最终脱敏检查5;失败0,无编译警告 | runs/20260923080423_b6797743868d42ee98f87ff7b4b91dd1/result.json |
| dotnet run --no-restore --project CodexOutput/upserver/KVContractTests | 退出0,42/42 | stage2.log |
| dotnet run --no-restore --project CodexOutput/upserver/KVSyncTests | 退出0,86/86 | stage3a.log |
| dotnet run --no-restore --project CodexOutput/upserver/KVSyncCoordinatorTests | 退出0,29/29 | stage3b.log |
| dotnet run --no-restore --project CodexOutput/upserver/KVSyncCoordinatorReviewTests | 退出0,1项通过 | stage3b-review.log |
| dotnet run --no-restore --project CodexOutput/upserver/KVStage3CTests -- --offline | 退出0,8/8 | stage3c-offline.log及3C的新离线run |
| dotnet build --no-restore CodexOutput/upserver/KVLiveTests/KVLiveTests.csproj | 退出0,0错误/0警告;没有运行 | live-build-only.log |
| uloop compile --project-path C:/projects/ft/Client --wait-for-domain-reload true | 退出0,0错误/0警告 | unity-compile.json |
Unity初次连接失败,确认该项目Editor未运行;启动项目指定2022.3.62f2c1后,get-version确认DataPath=C:/projects/ft/Client/Assets、CLI Loop 2.2.0,再编译通过。没有PlayMode或打包。unity.log保留首次失败,unity-compile.json是最终结果;unity-editor.log是本地原始编辑器诊断,不作为脱敏交付JSON。
三个旧csproj在测试后仅规范为原换行格式,使移除新增一行后字节内容相等;没有改变已测编译条目/源码/行为,不重复整套回归。
## 4. A1–A12逐项矩阵
以下为原交付技术验证;现已由外部独立复核及主会话逐条裁决接受,详见关闭裁决§3。
| 编号 | 具体用例/实际观察 | 结论 |
|---|---|---|
| A1 | A1-ready-merged-detached-snapshot:baseline/pending/localOnly合并、Delete缺席、快照不可修改且后续写不改变旧快照、携带Owner/玩家/epoch | 通过 |
| A2 | A2-validation-cancellation-and-reopen:未认证、ID/API不符、提前取消0Handler;A2-close-during-initial-get:忽略取消Get不提前返回、不发布句柄,收尾后可重开 | 通过 |
| A3 | initial-read-failure-releases-slot、busy-recovery-storage-errors:失败后可重开;conflict-unknown-no-empty-save:Conflict/Unknown/StorageError拒读,Data=null;close/create-cleanup-failure-blocks-reopen:清理异常不丢槽位/Task、后续CloseFailed | 通过 |
| A4 | A4-A6-A7-close-drain-queue-cancellation-stale-handle:101写传输闸门忽略取消,Close/102 Open仍未完成;释放后才开102,MaxActive=1 | 通过 |
| A5 | A5-repeat-open-close-single-owner:同账号重复Open不同Owner且旧句柄失效;重复Close返回同一Task | 通过 |
| A6 | 旧101句柄Update/Delete/Flush/Read/Wait拒绝;102快照为空且写请求数不变 | 通过 |
| A7 | 关闭未完成时排队Open取消立即返回Cancelled;原Close及后来的有效Open仍受闸门约束并完成 | 通过 |
| A8 | read-during-flush-preserves-batch:在途Flush时合并视图正确、不改变发送数/批次;epoch-invalidated-after-read:读后归属失效拒绝;stale-priority-over-not-ready:异常分支优先Stale;read-close-reentry-drains-lease:Close等待读租约,读不发布失效快照 | 通过 |
| A9 | login-session-dispose-or-relogin:session提前Dispose或重登换Cookie后,读/写/Wait拒绝,桥接仍完成Close且0变更发送 | 通过 |
| A10 | pending-reopen-no-implicit-flush:关闭0写,同账号新session重开读到pending,再显式Flush确认 | 通过 |
| A11 | default-transport-configuration只构造并检查默认handler,无Send;所有实际登录/Get/写走synthetic.invalid替身;输出扫描0敏感命中 | 通过 |
| A12 | 42/86/29、Review、3C离线、KVLiveTests只build、Unity通过;源码范围及三个csproj单行差异核验通过 | 通过 |
补充:A3-write-unknown-retains-ticket-semantics验证Unknown票据保留,不返回可玩数据、不再次发写。
并发由TaskCompletionSource闸门、读边界回调和token事件控制,未使用Sleep推断顺序。
## 5. 脱敏与传输边界
[artifact-and-transport-check.json](KVGameBridgeTests/artifact-and-transport-check.json):4A result.json中fixture key/value、Cookie/Token敏感字段、用户名路径均0命中;accessedFormalServer=false。
证据依据是实际调用路径:登录及Bridge内部工厂均替换为限定synthetic.invalid的Handler,默认HttpClientHandler仅反射获取并检查配置,KVLiveTests仅构建。该字段不是独立网络抓包结果。
缓存仅位于新测试run/cache,保留合成值和故障证据。故意Close失败案例保守保留锁到测试进程退出,属于离线反例,无正式账号遗留。
## 6. 自审、限制与下一步
[限定代码自审](阶段4A限定代码自审-2026-09-23.md)及外部独立实施复核均完成,无待修复P1/P2;P3-1偶发测试失败根因未定位,按关闭裁决保留后续跟踪。
Close失败不自动恢复;同一桥接会返回CloseFailed。业务调用者需保持固定句柄,不能自行把旧回调转成“当前账号”保存。isCurrent应为轻量归属判定,不可同步等待自己的Close。新接口不承诺游戏存档已迁移,也不改变3A/3B保守恢复语义。
4A已关闭。下一步审查[4B分期与4B1方案](阶段4B分期与4B1登录存档准备方案-待评审-2026-09-23.md),通过并裁决后才编码,不直接继续游戏接线。