Files
ft/CodexOutput/upserver/阶段4B3分期与4B3A方案独立审查-2026-09-24.md

53 lines
6.5 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.
# 阶段4B3分期与4B3A方案独立审查
日期:2026-09-24。审查者:ZCode会话。
**独立性声明**:未参与本方案及任何4B3源码实施(4B3尚无业务代码);此前参与为4B2期D1–D5差异审查与4B2实施复核(受审对象均为主会话编制)。本轮为设计审查,未运行游戏;仅只读核对与文件hash计算,新增本报告,未改方案/代码/共享文档/原受审产物。
## 受审版本核对
| 项 | 结果 |
|---|---|
| `阶段4B3方案受审基线-2026-09-24.json`(39项) | **全部一致** |
| `mustRemainAbsent`(7项:新结果类/新Editor host/新Editor转接/新测试目录) | **全部确认不存在** ✓ |
| `B3DesignAudit/source-hashes.json`(2101项源码清单) | **2101/2101全部一致,无缺失/漂移** |
| `B3DesignAudit/calls.json` | 223条语法调用与方案声明一致;`classification.json`为逐调用分期建议(B3-C001…)——**事实台账口径核实**,未冒充隔离合同 |
## 裁决A:4B3分期——**通过**
- **A(固定存档入口)→B(业务归属/内存隔离)→C(加载发布/生命周期)三分合理**:A是B的前提(业务迁移需要带guard纪律与固定句柄规则的访问面,否则每个B入口各造一套顺序);不重复4A(4A句柄是机制,A是被guard约束的访问面);"一次全改"与"Instance自动取当前句柄"两条否决理由成立(后者正是旧回调写新账号的病灶)。
- 223调用/81文件被正确标注为**事实台账**(calls/classification为语法盘点+名称匹配候选,方案§1明示无语义绑定、未证明事件/反射/UnityEvent链完整)——分期理由成立,未被包装成"全链隔离已设计完成"。
- B/C未被本轮提前批准(§2表"另审/必须先完成B"、§5合同明示"约束而非实施批准");方案§4如实承认A的guard检查是**入口观察而非跨操作租约**、切换竞争归C、A不宣称自动保护业务共享内存——无"未来不启用"式自我豁免。
- A单元本身不薄:四个入口+guard优先级+键读取语义+透传合同+兼容验证,构成B必需的最小地基。
## 裁决B:4B3A完整方案——**通过**(无P1/P2;P3四条)
逐项核查结论(附源码依据):
1. **四入口设计**:internal static、不访问Instance/场景/Prefs/旧缓冲、无新静态字段/定时器/重试——与`PlayFabMgr`现状兼容(guard类`PlayerKVGuardPoint{Compare,ReadLocal,Update,Immediate,Sync,Lifecycle,PrefsSave}`**已含ReadLocal**,`Reject/Count/RequireLegacyAllowed`internal static同程序集可达,方案§3.1的读取顺序有实现基础)。
2. **ReadKV语义**:guard优先→InvalidInput→单次`ReadLocalSnapshot`→Ordinal查询;缺键`Found=false`与空串`Found=true`区分、失败`Found=null`禁伪缺键、快照≠未来许可——闭合。`KVSnapshot.ValidKey`既有规则(非null/非空/≤128、不Trim不改大小写)复用,internal可达。
3. **Write合同**:原样透传StateResult/Ticket/`LocalCommitMayHaveSucceeded`;Accepted≠Confirmed表格明确"不允许作出的判断";remote=false不清旧remote pending(沿用3A语义,B3A-05双向验证);null不偷改Delete、无Delete facade(当前无业务需求,诚实)。关闭竞争保留实际接受事实、不改发B。
4. **Flush/Wait**:无第二水位/无新定时器;guard命中返回结构化零计数结果;取消仅结束等待、排水归既有Owner;Superseded/Unknown不压成bool。
5. **B2兼容**:四入口全服从既有guard并计入现有违规计数(§4);私有handle保持private;公共kv仍BackendNotEnabled;LoadedForValidation不获写权限。
6. **白名单可实施性**:PlayFabMgr"仅新增块+旧区字节保持"可检验(B3A-15移除后字节一致);**ServiceHost通配纳入条件核实**——`ServiceHost.csproj`现有`UNITY_EDITOR;SERVICE_HOST`定义+`PlayerKV*.cs`通配+既有Editor host显式Exclude,新结果类经通配纳入、新Editor host用`UNITY_EDITOR&&!SERVICE_HOST`内容包裹即可,**无需改旧csproj**(PlayerProbe仅`SERVICE_HOST`定义的现有行为保持)✓。
7. **验证host安全**:`kv-route.invalid`固定合成传输、固定case、guard TryEnter、finally先Bridge排水再Dispose session、不覆盖静态单例——闭合。
8. **B3A-01~19覆盖**:充分且诚实——特别是B3A-07的**证据分层**:StorageError uncertain=false用真实IO路径(`state.json.tmp`目录使实际写失败)注入、uncertain=true(AfterReplace)沿用KVSyncTests既有五阶段fault回归+facade原样return源码审计,不宣称新facade端到端注入、不为注错修改readonly底层——这是正确的最小改动取径。B3A-18保留两项间歇首败事实不以重跑覆盖。
9. **旧PF回归**:B3A-15(字节比对)+B3A-18(全量回归)双保险;guard无租约直通的行为回归经4B2 ServiceHost既有双条件宿主保持。
**P3清单**:
- **P3-1**:B3A-03/07的`state.json.tmp`目录技巧——建议实施时在测试finally中删除自建目录并断言无残留(避免runs目录累积假"RecoveryRequired"干扰后续扫描)。
- **P3-2**:四个internal static方法在Player构建中保留为无调用者代码——无害(可能被剥离),建议实施记录注明"Player中无生产调用路径"的链接期观察。
- **P3-3**:`PlayerKVKeyReadResult`建议在XML注释中显式说明"Found=null(失败)与Found=false(有效快照缺键)的三态语义",防B3B接线者误用`Success?..:default`模式。
- **P3-4**:§3.2表格"Blocked|原Owner/状态不准入|不允许:改取当前B账号句柄再写"——建议B3B合同时补充"Blocked后正确行为=中止并走归属恢复流程"的指引(防实现者把'不允许'误解为'须换句柄重试')。
## 残余限制(如实保留)
- 223调用台账无语义绑定;B/C的逐入口合同、白名单、内存归属验证均未设计——**本通过不授权B/C编码**。
- A无生产调用者:通过≠任何业务已走KV;加载后写接通属C。
- KVSync StorageError与3C L7两项间歇首败根因未定(4B2复核已立档);P2-α真实档迁移专项+用户产品确认、4C、tickets、身份与4D启用门全部保持。
- 本报告仅为方案结论:不宣布实施完成、4B3关闭或G4通过。
## 结论
**A:通过(分期合理)。B:通过(P3四条,建议随裁决采纳为实施说明)。** 建议主会话核对hash(本报告已代验39+2101项一致)后逐条裁决,按§8检查点0–4实施4B3A,交付后交独立实施复核。