Files
ft/CodexOutput/upserver/阶段3C独立方案审查-2026-09-23.md

78 lines
7.8 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独立方案审查
日期:2026-09-23。审查者:独立方案审查AI(ZCode会话,由用户指定)。审查对象与范围:仅文档审查——[3C方案](阶段3C组合与限定联调方案-2026-09-23.md)、[实施任务书](阶段3C实施任务书-2026-09-23.md)、[验收矩阵](阶段3C验收矩阵-2026-09-23.md)、[方案审查清单](阶段3C方案审查清单-2026-09-23.md);对照阶段3主方案、3B文档终审、服务端4xx核查及现有生产源码核对可执行性。本轮未修改任何生产代码、测试、配置或共享文档,仅新建本文件。
四份待审文档SHA256已逐项核对,与审查提示词所列基线完全一致(`16718D63…`/`D0029D31…`/`8B00E33D…`/`3771CF20…`)。
## 裁决
**通过。** 未发现P1/P2级方案问题。方案在现有生产接口内可完整实现,正式服安全边界(manifest先行、受限转发Handler、碰撞不删、Unknown停止、双会话清理确认)自洽且与已验收的3A/3B保守语义一致。下列6项均为P3级澄清建议,建议主会话裁决时采纳为实施说明,不要求重新评审轮次。
## 可行性核对(对照生产源码与服务端)
| 核对点 | 结论 |
|---|---|
| 受限Handler注入路径 | `PlayerKVSessionOwner.CreateAsync`的internal重载接收`handlerFactory`/`transportTimeout`;测试宿主直接编译生产源码(同程序集)即可访问,3B的KVSyncCoordinatorTests已验证同一模式。可行 |
| Owner初始化"全量Get"识别 | `PlayerKVClient.GetAsync(null)`请求体不含`keys`;受限Handler可据此识别并改写为manifest keys。可行 |
| 服务端过滤Get语义 | N3-Server-CN(858fe7c)`PlayerKVService.GetAsync`对带keys请求只返回存在的键。过滤Get不会返回越界key。可行 |
| live模式登录与Owner传输分离 | `S101AccountSession`自身handlerFactory与Owner的handlerFactory相互独立:登录走真实默认handler,Owner走"真实HttpClientHandler外包受限转发层"(Cookie由内层UseCookies=true处理)。可行 |
| L0断言素材 | `S101AccountSession.PlayerId`/`NewlyCreated`公开暴露。可行 |
| O5诊断素材 | `PlayerKVSyncState.Open`/`Inspect()`公开;`KVIdentity`环境指纹规则=规范API的SHA256,与诊断"API指纹"字段同源。可行 |
| key长度 | 前缀`codex_kv_s3c_YYYYMMDD_<32位guid>`约53字符+后缀,满足服务端128字符上限。可行 |
| §2.3不扩展KVLiveTests的理由 | 核实KVLiveTests.csproj确用`PlayerData/*.cs`通配符;扩展会破坏阶段边界(同3B步骤0.1裁决的问题)。理由成立 |
| 回归与hash门 | 42/86/29命令、3B终审基线hash门与既有证据链一致。可行 |
## 发现清单(全部P3,不阻塞)
**F1|§4.2.4措辞:"发现空集合以外的越界key时…拒绝"含糊。** 触发:Get无keys是Owner初始化的正常形态(必须改写转发而非拒绝);Set空data是服务端no-op。影响:实施者可能把Owner初始化Get当越界拒绝。最小建议:改写为"Get无keys改写为manifest keys;Set/Delete请求中出现任何不属于manifest的key即在网络前整体拒绝(Set空data按no-op放行)"。
**F2|越界拒绝经完整Owner链路时的表象是Unknown冻结。** 触发:`PlayerKVClient`对变更请求的一切非200/传输异常均保守标`MayHaveCommitted=true`,3B据此冻结Unknown——这是正确保守行为,但H2若经Owner全链路验证,预期结果是Unknown而非"确定失败"。影响:实施者可能误判为缺陷或试图让拒绝"确定失败"。最小建议:H2按任务书检查点4保持单元级断言(对受限Handler直接断言内部转发计数=0);如经Owner链路,应使用一次性run目录并断言"计数=0且状态冻结为Unknown"。建议在§4.2补一句说明。
**F3|§7"票据状态计数"来源未指明。** `Inspect()`不含票据信息,Owner关闭后coordinator不可查询。影响:实施者可能寻找不存在的生产接口。最小建议:明确由测试宿主在关闭Owner前通过票据对象、`WaitForTicketAsync`结果和`FlushAsync`汇总自行累计。
**F4|O2子进程A依赖"干净Close后退出"。** Close不隐式Flush的契约以A正常收尾(释放文件锁、无遗留tmp)为前提;父进程超时强杀只能作为失败路径。影响:若把强杀当正常步骤,B会读到RecoveryRequired而非pending。最小建议:O2注明"A正常Close并退出后才启动B;超时强杀视为该用例失败并保留run目录"。
**F5|§2.1未写非法参数退出码,矩阵S0要求非0。** 最小建议:方案补"以非0退出码退出"。
**F6|manifest允许保存完整测试key,日志合同可再收紧。** manifest在任务目录内可接受;但建议§8明确result.json与log同样不得回显完整key(只出现runId/数量/状态),与D3诊断规则保持一致。
## 审查清单逐项
### A. 范围与前置门 — PASS
- PASS:3C只做组合、限定fixture、诊断与证据,不接游戏入口(方案§1)。
- PASS:默认无生产文件修改;接口不足返回差异评审(方案§3;且本审查确认现有接口足够,见可行性核对)。
- PASS:主会话实施、其他AI本轮只审(任务书§1前置门)。
- PASS:API/账号/模式/缓存根固定(§1、§4.3,路径限定于runs/<runId>/cache)。
### B. 正式服安全 — PASS
- PASS:manifest在任何变更前落盘,key预登记,运行时不可扩大(§4.1+Handler白名单固定于manifest)。
- PASS:碰撞预检失败不删碰撞key且cleanupAllowed=false(L0)。
- PASS:受限Handler以"Get改写为manifest keys+响应仅含manifest key"阻断业务KV进入测试缓存(§4.2.3;服务端语义已核实)。
- PASS:Set/Delete越界网络前拒绝;禁重定向/重试/全量清理(§4.2)。
- PASS:正式服不制造Unknown/超时/断网/4xx/迟到写(§1;矩阵注明故障仅合成)。
- PASS:Unknown→停止写、hadUnknownWrite落盘、原运行永久失败;--cleanup不改写通过、不解除生产Unknown(L4)。
- PASS:清理只按manifest、双新会话读回为空(L3/L6)。
### C. 组合和并发 — PASS
- PASS:离线直接使用真实Owner+3A状态+3B协调器,不重实现状态机(§5)。
- PASS:跨进程pending/文件锁步骤有确定超时(O2;F4为补充说明)。
- PASS:诊断导出只读(关闭后经`Inspect()`),不改变Unknown/RecoveryRequired策略(O5)。
- PASS:101/102命名空间隔离与API指纹隔离均有明确用例(O3/O4;"IP与s101.local不视为同环境"与3A KVIdentity一致)。
### D. 诊断隐私 — PASS
- PASS:专用DTO,不直接序列化DiagnosticSnapshot(§7)。
- PASS:禁止Cookie/Token/正文/值/业务key/原始测试key/用户名路径;key仅SHA256(缓存根以任务内相对路径记录,规避了用户名路径)。
- PASS:数量、序号、状态、错误类别足以定位问题。
- PASS:诊断失败不改缓存、不删证据(O5)。
### E. 可执行性和验收 — PASS
- PASS:允许文件、命令、结果格式、退出条件完整无歧义(任务书§2/§4/§5;F5为补充)。
- PASS:无TBD/TODO;不依赖服务端CAS/revision/幂等查询;阶段2证据不复用为3C证据(验收门要求全新执行)。
- PASS:42/86/29回归、Unity编译、生产hash一致、实施后独立审查均为强制门(§9)。
- PASS:清理失败、Unknown、越界请求、生产hash变化均明确阻塞(§9末段)。
- PASS:真机、游戏接线、PlayFab替换/SDK删除明确未完成(§1、§9)。
## 审查者边界声明
本轮仅新建本审查文件;未修改任何生产代码、测试、csproj、方案文件或共享README/TODO/开发状态/接手入口。裁决权归主会话:建议将F1–F6采纳为实施说明并把任务书状态改为"已批准实施"后开始3C开发。