53 lines
6.5 KiB
Markdown
53 lines
6.5 KiB
Markdown
# 阶段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,交付后交独立实施复核。
|