Files
ft/CodexOutput/upserver/阶段3C补修复交付与逐项证据-2026-09-23.md

96 lines
10 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.
# 3C补修复交付与逐项证据
> 最新终审:用户指定外部AI复核接受,无新P1/P2;主会话核对版本并裁决R1–R5/F2关闭,3C/G3通过。见[终审裁决](3C补修复终审裁决与4A准入-2026-09-23.md)。下方“待外部复核”等表述为当时状态,最新结论以本注为准。
日期:2026-09-23。实施者:主会话。**R1–R5已修复并完成本轮技术验证,等待用户指定外部AI实施复核;不宣布3C/G3最终通过,4A未启动。**
## 1. 代码与边界
- 仅修改 [Program.cs](KVStage3CTests/Program.cs),SHA256:66C41B8B0A8E0CD4FF13A3BED8212B3F61BF95E4707F5C6373B235E21B20492A。
- csproj未改,SHA256:27CC1AF41AC658EA9B8DE1ACB35E37058C294A93D30E232D42B9AFCBDD95A1E6。
- 八份链接生产源码与修复前记录一致;七份KV文件有3B历史基线,账号类仅按本次修复前基线核对。完整hash见 [repair-final-source-hashes.json](KVStage3CTests/repair-final-source-hashes.json)。
- 没有修改服务器、生产KV/登录、游戏入口、SDK或Unity配置;没有打包。故障均使用simulation,没有在正式服制造故障。
## 2. 修复效果
| 发现 | 最终实现 |
|---|---|
| R1 超时和清理重叠 | linked CTS贯穿登录/Owner/直接请求;超时禁止新写、先保存失败/不确定状态,取消后等待body及Close真正结束;原运行超时/Unknown不自动cleanup;独占run.lock排除并发执行。 |
| R2 manifest边界 | schema2严格字段/类型/重复属性解析;固定API、账号、runId、prefix及精确三个key;同run绑定、相对cache和路径/重解析点校验;登录前拒绝无效manifest;合法cleanup只输出key哈希。 |
| R3 失败结果被升级 | manifest保存原断言及执行状态;原result/log使用CreateNew不可覆盖;显式补cleanup产生独立JSON,只更新清理事实,原失败保持失败;Completed要求原断言通过且无未知/超时及两账号清理。 |
| R4 正式读回不足 | Delete前种值并确认存在;精确核对两账号不同值;新Cookie/Owner打开同缓存并经Get观察Ready;102后再次读取101;关闭后核对真实快照。 |
| R5 组合和证据缺项 | C子进程真实Get/Ready/精确值;Unknown重开后主动Flush且所有handler共享计数;损坏主档有效备份、缺主档bak/tmp、有效主档坏bak;失败编排、跨进程锁、Cookie/票据/环境隔离;诊断区分关闭前Ready和重开未Get的NotLoaded。 |
交付前自审补强:失败批次可能留下尚未结束的后续票据,不等待它们阻塞Close;失败只记录实际Flush汇总,成功才等待Confirmed票据。新增第二批Set未知、Delete尚未发送反例。参见 [限定自审](阶段3C补修复限定自审-2026-09-23.md)。
## 3. 实际执行与产物
所有命令在C:/projects/ft执行。使用现有依赖,避免默认restore读取受限的用户NuGet配置。
| 命令 | 退出码/结果 | 证据 |
|---|---|---|
| dotnet run --no-restore --project CodexOutput/upserver/KVStage3CTests -- --offline | 0,8组通过 | O目录result/log/diagnostic及child日志 |
| dotnet run --no-build --project CodexOutput/upserver/KVStage3CTests -- --live-s101 | 0,3条业务场景及双账号清理通过 | L目录result/log/manifest/diagnostic |
| dotnet run --no-restore --project CodexOutput/upserver/KVContractTests | 0,42/42 | repair-stage2.log |
| dotnet run --no-restore --project CodexOutput/upserver/KVSyncTests | 0,86/86 | repair-stage3a.log |
| dotnet run --no-restore --project CodexOutput/upserver/KVSyncCoordinatorTests | 0,29/29 | repair-stage3b.log |
| uloop compile --project-path C:/projects/ft/Client --wait-for-domain-reload true | 0,错误0/警告0 | repair-unity-compile.json |
最终证据目录缩写(下面每行使用):
- **O**:[最终离线run](KVStage3CTests/runs/20260923073652_de06350b988e4d1db4fc89937259a024/),runId为20260923073652_de06350b988e4d1db4fc89937259a024。
- **L**:[最终正式run](KVStage3CTests/runs/20260923073720_199d4e8a22204ae5882057b1503092c6/),runId为20260923073720_199d4e8a22204ae5882057b1503092c6。
- **E**:[补修复证据根目录](KVStage3CTests/)。
- 目录内manifest/result/diagnostic/log文件名均为runId加相应后缀。
- 正式API固定http://s101.local:18080/;101/102;prefix和三个fixture key在L的manifest登记,报告不回显key或值。最终8张写票据Confirmed;每账号2次独立新会话清理读回为空;HadUnknownWrite=false、TimedOut=false、InFlight=false、Completed=true。
- 首次正式run 20260923073436_93b968171816414d8d0bec769a1acbad也已清理。因最后一次失败路径补强后源码hash变化,重跑得到L;两次证据都保留。
- 42/86/29与Unity在最后测试宿主失败分支补强之前执行;对应生产源码、Unity配置、既有回归源码没有后续修改,故未无意义重复。
- 原始历史run和外部审查原文未覆盖;simulation失败manifest是离线反例,不是正式服遗留待清理项。
## 4. 逐行验收映射
“本轮通过”是实施证据结论;独立验收门F2仍待完成,不能把分组数当作所有门自动通过。
| 矩阵项 | 具体测试/断言 | 产物位置 | 本轮结论 |
|---|---|---|---|
| S0 | 无参数、非法参数、非法child参数退出2;不创建run;Main分派在任何登录前退出 | E/repair-cli-guards.json、Main源码 | 通过 |
| S1 | 固定API/账号;错误API/账号/mode/字段类型等在登录前拒绝,计数0 | O/diagnostic guard条目;ManifestNegativeCases | 通过 |
| S2 | CreateManifest先保存;BeginWrite在转发前写InFlight;preflight两账号完成才授权写/cleanup | L/manifest;ExecuteOriginal、BeginWrite源码;离线碰撞反例 | 通过 |
| S3 | 同run精确绑定、cache固定相对路径;穿越、跨run、junction拒绝 | O/diagnostic;ManifestNegativeCases/CheckPath | 通过 |
| O1 | Set/Delete/localOnly/Flush真实Owner;关闭重开pending0、localOnly1 | O/state与ticketCounts;OwnerCombination | 通过 |
| O2 | A落盘pending、B恢复Flush、C新Owner Get后Ready且精确值/无pending | O/child-a/b/c.log、child-c-observation.json | 通过 |
| O3 | 独立Cookie身份、102缓存无101意图、跨Owner票据Blocked;正式值隔离 | O/diagnostic isolation条目;IdentityAndLock;L | 通过 |
| O4 | 不同API命名空间没有原baseline/pending/localOnly | O/diagnostic isolation条目;IdentityAndLock | 通过 |
| O5 | 未Close同进程/子进程Busy,Close后可重开 | O/child-lock.log;IdentityAndLock | 通过 |
| O6 | 远端观察基线/目标均Unknown;新旧handler合计仅一次写,重开后Flush不重发 | O/log O6;ConservativeUnknown | 通过 |
| O7 | 坏主档+有效备份、缺主档bak/tmp均RecoveryRequired | O/log O7-O8;CorruptionPolicy | 通过 |
| O8 | 有效主档+坏bak仍可打开 | O/log O7-O8;CorruptionPolicy | 通过 |
| D1 | 从真实Flush/票据累计,Owner关闭前状态/epoch/实例ID,重开快照NotLoaded及序号/数量;错误类别 | L/diagnostic、O/diagnostic;Confirm/VerifyOwner | 通过 |
| D2 | DTO仅手工选取状态元数据;扫描Cookie/Token字段、值、正文、用户名路径 | E/repair-artifact-scan.json;WriteArtifacts | 通过 |
| D3 | 完整fixture key不出现在diagnostic/result/log;只保留哈希 | E/repair-artifact-scan.json;WriteArtifacts | 通过 |
| H1 | 空Get改写为manifest三个key,返回越界key拒绝 | O/diagnostic handler-guards;HandlerGuards | 通过 |
| H2 | 越界Set/Delete不转发;Owner越界本地接受后Flush零写请求且Unknown | O/diagnostic outOfScopeMutationRequests=0;HandlerGuards | 通过 |
| H3 | handler绑定捕获Cookie、UseCookies=true、AllowAutoRedirect=false;错误响应一次无重试 | O/diagnostic responseAttempts=1;RealHandler/LiveAccount | 通过 |
| L0 | LiveLogin检查成功、输入身份匹配、非新建;不单靠PlayerId推断服务端身份 | L结果;LiveLogin;另结合L3的服务端值隔离 | 通过 |
| L1 | 两账号限定key碰撞预检为空才授权 | L/manifest CollisionPreflight=true;离线collision反例 | 通过 |
| L2 | 101种值、写/删、票据Confirmed、新Owner Ready | L/diagnostic playerId101、result | 通过 |
| L3 | 102不同值;写完再重开101并精确比较 | L/log reread-101-after-102、diagnostic | 通过 |
| L4 | 每次登录独立Cookie,重开不同Owner;同缓存Get和无pending/unknown快照 | L/diagnostic三个post-close-reopen;EnvironmentIO.Jars检查 | 通过 |
| L5 | CleanupCore精确m.Keys;RestrictedHandler再次约束 | L/manifest/result;CleanupCore源码 | 通过 |
| L6 | 101/102分别两次新会话Get为空 | L/manifest CleanupReads均2;log双清理行 | 通过 |
| L7 | 超时忽略取消闸门;Unknown;后续批次未知;失败清理;原失败补清理不得升级 | O/diagnostic case条目及所列simulation run,LifecycleGuards | 通过(synthetic) |
| R1 | 阶段2回归42 | E/repair-stage2.log | 通过 |
| R2 | 3A回归86 | E/repair-stage3a.log | 通过 |
| R3 | 3B回归29 | E/repair-stage3b.log | 通过 |
| U1 | Unity CLI Loop编译错误0/警告0 | E/repair-unity-compile.json | 通过 |
| F1 | 八份生产文件与修复前hash一致,csproj一致 | E/repair-final-source-hashes.json | 通过 |
| F2 | 设计独立审查及主会话裁决已完成;实施者自审已完成 | 设计审查/裁决、限定自审 | **外部实施复核待完成** |
## 5. 限制与交接
- 原运行超时/Unknown不自动清理;只有后续显式cleanup可补救。忽略取消并永久不返回时保持等待,不宣称已收尾。
- 崩溃遗留Running/InFlight的manifest被拒绝补cleanup;需人工核查,无自动恢复/解锁。schema1历史manifest不自动升级。
- 本轮真实正式run均清理完毕,无需再次cleanup;模拟Unknown遗留仅为离线证据。
- 磁盘永久不可写时无法保证最终结果文件写成,但manifest会尽可能保留失败/在途状态,不能按无文件推断通过。
- 不包含游戏存档接线、PlayFab移除、真机和打包;这些仍在后续阶段。
- 下一步把 [外部AI复核提示词](其他AI审查提示词-3C补修复实施-2026-09-23.md) 交给用户独立AI。无P1/P2且逐条裁决后,才可恢复3C/G3并批准4A编码。