iter33 卡① 独立验收审计通过(两轮):首轮 sv3/sv4 缺漏记录+回炉复审通过(sv1-sv14 全过)

This commit is contained in:
DKChan committed 2026-10-22 04:30:43 +08:00
1 parent 4a8558a09f
commit 565f5e86c3
1 file changed
+97
+97
View File
@@ -0,0 +1,97 @@
# 迭代 33 独立验收审计(2026-10-21)
> 审计人:未参与实现的独立会话,只采信盘面证据与自跑实测,不采信任何报告的「已全绿」。
> 被审计对象:卡① 存档制数据层改造批(worktree `D:\code\g-plan2-iter33card1-save`,分支 `iter33-card1-save`,实现提交 `6a7c2575`+`074cfe27`,基线 `7280070f`;首轮审计后回炉提交 `4a8558a0`,见文末复审小节)。
> 审计材料:需求卡片 §7.1/§7.2、实现报告卡① 节实际对照表与变异记录表、`git diff 7280070f..HEAD`、三个新单元套件+冒烟新段+run_all 注册、闸回执。
> 审计自跑基线(首轮,HEAD=074cfe27):冒烟 **1201 项 / 0 失败**(`python tools/run_smoke.py`,三闸全过);单元 **38 套件全绿**(`--script res://tests/run_all.gd`)——与实现报告读数一致。
> 复审自跑基线(回炉后,HEAD=4a8558a0):冒烟 **1201 项 / 0 失败**(三闸全过);单元 **38 套件全绿**;boot 套件 **12 检查全绿**——均为审计自跑实测,见复审小节。
## 卡① 存档制数据层改造批
### ① 逐行核对表(sv1–sv14,对实现报告实际对照表逐行复核)
| # | 判定 | 依据(审计自查实录) |
|---|---|---|
| sv1 三槽承载+位间隔离 | 通过 | 两落点在盘:单元 `save_slot_isolation_test.gd` ①段+冒烟 `_smoke_save_slots` ①段;〔sv1〕尾缀 grep 命中(冒烟 4 处、单元多处)。真实入口=卡片申报面(SaveManagerCore 按槽 API 直调,不经 UI)未绕过。变异①(slot_path 写死 `% 1`)机理静态复核成立:三槽同名文件则槽 2/3 异值读回必不成立。 |
| sv2 启动态不读盘 | 通过 | 真实入口在位:冒烟 V2-s1/V2-s2 挂真实 autoload boot 链(`main.get_node("/root/SaveManager")`,`_smoke_boot_chain` 内)。单元为类级白盒面——计划落点仅单元、实测拆双落点,报告已如实对账(非隐瞒)。变异④机理成立:`_ready` 偷激活则 V2-s1 `active_slot()==0` 直接判红。 |
| sv3 无激活写盘拒绝 | **缺漏**(首轮判;回炉后复审通过,见文末复审小节) | 见结论缺漏 1。两点:申报真实入口(`MetaProgression.settle_adventure` 链触达写盘被拒)零对照面——单测与冒烟 V2-s3 均裸调 `write_to_disk`,无任何 MetaProgression 链在无激活态下触达写盘的断言;撤销证明经审计实测**不成立**(拆闸后全部 sv3 断言仍绿,详②-2)。报告 sv3 行「代码评审可证」的撤销主张被实验推翻。 |
| sv4 新档原语 | **缺漏(轻)**(首轮判;回炉后复审通过,见文末复审小节) | 断言在盘(冒烟 ③段)且入口合规;但申报变异「新档写成读旧档」未执行,且经流程点推演**无判别力**:冒烟段序为②段先删槽 3、③段才 create_slot(3),此时槽 3 无文件——「读旧档」变体读不存在文件=回默认态,全零断言仍绿。报告以推理代实测(「与 sv5 读回断言同族必红」),未按 test-conventions §6 标「拦截能力未证」。见结论缺漏 2。 |
| sv5 进档原语 | 通过 | 冒烟 ①④段+单元多落点;〔sv5〕grep 命中。变异⑤已执行且机理成立:激活不落 `_path` 则首槽写盘受理返回 false,「sv3 激活态写盘受理」判红——与报告变异表⑤一致。 |
| sv6 删档原语 | 通过 | 冒烟 ②段直接盘面断言(文件不在盘+无 .tmp+指针清除+他槽字节不动)。变异②(短路文件删除)经审计**静态推演**成立:在盘断言直查 `FileAccess.file_exists`,短路即红;⑥段空槽窥视连带红(与报告变异表②的红集一致)。未实测(报告已申报全量冒烟实测),推演记录于②-3。 |
| sv7 摘要三项按槽窥视 | 通过 | 单元 12 检查+冒烟 ⑥段双落点;窥视不激活不写内存有专断言(active_slot==0)。**变异③审计实测复现**:注入读激活态 → `save_slot_summary_test` 红(sv7 逐槽·槽 3+坏槽/高版本/缺版本三不可读态,详②-1)→ 还原 → 12 检查全绿。 |
| sv8 窥视三态零副作用 | 通过 | 冒烟 ⑥段+单元 ③段字节+mtime 双比对+零 `.corrupt.bak` 改名+.tmp 按空槽。变异未实测;静态推演成立:窥视改走正式 `load_from_disk` → `_corrupt_fallback` 改名主文件消失 → 「零改名」断言红。判据面(字节+mtime)实测在案于双落点。 |
| sv9 迁移链各槽成立 | 通过 | 冒烟 ⑤段三槽各喂 v5 旧档逐槽读回+写盘 version=7;既有迁移段(v1/v2/v5)全数复跑绿(审计自跑基线在案)。变异「迁移只跑激活槽」机理静态成立:他槽激活读回值必不成立。 |
| sv10 切槽同实例整体替换 | 通过 | 单元 ③段宿主链:`MetaProgressionScript.new(null, t)` 真实宿主链、`meta.save == t` 引用同一、读数随槽(533→644)、写盘 650 落槽 2 并盘面核验、高版本槽激活失败恢复切换前三态。变异⑤覆盖「写盘落错槽」半面;「新建实例」半面为 API 形状所禁(方法内无从换实例),推理可证。meta_progression.gd 零改动(diff 核实)。 |
| sv11 测试隔离面保留 | 通过(附注) | 非新断言行——卡片申报即「既有段全数复跑」,无代码尾缀可 grep 属申报内形态,非缺漏。凭据:审计自跑基线冒烟 1201/0(含全部既有段)+单元 38 套件绿+回执探针 --click/--full 绿;T0 隔离面清点在实现报告§三(18+15 条、attach_path 8 处、tag 族、boot/lifecycle 四段、presenter lambda、真实档红线逐点判定)。attach_path「注入即激活+重读」语义在代码核实保持(注入槽名记账激活号、注入任意路径写盘目标照旧)。 |
| sv12 旧档处置 Q1 甲 | 通过(附注) | ⑦段夹具四断言钉死语义:逐域相等(1234)、源改名留痕、幂等(预置 777 零覆盖+源保留)、他槽字节不动;幂等变异静态成立(去 `dst` 存在判据 → 二次迁移覆盖 777 → 断言红)。V2-s4 挂真实 boot 链。附注:V2-s4 不变式(旧档在则槽 1 必在)在本机已迁移态下为空真——生产接线面的机检强度依赖盘面状态,但语义面已由夹具钉死,接线面拆毁在有旧档的盘面上仍会红,判可接受。⑦段直调 `_migrate_legacy_save` 为被测私有件本身,有 V2-s4 生产链对照面在,不判绕过。 |
| sv13 不升 schema 版本 | 通过 | **diff 核实零改动**:`SAVE_FORMAT_VERSION := 7` 行基线/HEAD md5 一致(`101adcd0ebe1a18f2004b454a8c85bb8`);`_normalize` 函数体逐字节一致(diff 空输出);迁移链函数零触碰(新窥视路径只读调用二者)。既有版本/高版本拒读断言复跑绿(基线在案+冒烟 ④段高版本槽断言)。 |
| sv14 反哺点清单 | 通过 | `reports/iter33-反哺点-2026-10-21.md` 在盘,六条全覆盖 §5:存档序列化.md :61/:20/:16/:165 四落点+新增迁移条款建议+待办清单+roadmap,各条有「现行陈述/应改成/依据」。件核不产码,合规。 |
### ② 撤销证明抽查记录(审计自跑实测,命令与输出摘要)
**②-1 变异③复现(报告变异表③,实测)**
- 注入:`game/core/save_manager.gd` `peek_slot_summary` 函数体首行插 `return {"readable": true, "keystone": keystone_balance(), "cleared": adventure_cleared(), "total": adventure_total()}`。
- `--headless --path . --script res://tests/unit/core/save_slot_summary_test.gd` → **FAIL**(窗内 4 条:`sv7 窥视三项逐槽正确·槽 3`+`sv7 坏槽窥视=显式损坏标记`+`sv7 高版本槽窥视=不可读标记`+`sv7 缺版本字段槽窥视=不可读标记`;更早 FAIL 行被输出窗口截断)——跨槽摘要与不可读态两面均被抓,拦截力实测成立。
- `git checkout -- game/core/save_manager.gd` → `git status --porcelain` 空 → 复跑 **all green (12 checks)**。与报告变异表③一致。
**②-2 自选变异:sv3 撤销证明检验(审计设计,实测——发现缺漏)**
- 注入:`write_to_disk` 无激活闸 `if _path == "":` 改 `if false and _path == "":`(即 sv3 行申报的撤销操作「去掉判定放行旧入口」)。
- 跑 `save_boot_no_activate_test.gd` → **仍 all green (8 checks)——申报的红未出现**。
- 原因查实:拒写断言锚在返回值 `false`,而空路径下游 `FileAccess.open(".tmp", WRITE)` 对 `"" + ".tmp"` 相对路径**打开成功并真实写盘**(实测运行在 worktree `game/` 落杂散文件 `.tmp`,657 字节,内容为序列化默认档 JSON),随后改名到空目标失败才返回 false——「闸拒绝」与「空路径写失败」在全部 sv3 断言(返回值+三槽存在性/字节/mtime)上不可区分;杂散 .tmp 落在项目根不在三槽扫描面内,零断言可抓。
- 还原:`git checkout --` → 复跑 **all green (8 checks)**;杂散 `game/.tmp` 已删除(审计产物清理,git-ignored 件,删后 `git status` 干净)。
- 判定:sv3 断言批对「拆闸」无判别力,撤销证明不成立。
**②-3 变异②(删档漏删)静态推演(审计设计,未实测——报告已申报全量冒烟实测)**
- 注入设定:`delete_slot` 文件删除分支短路(`if false and FileAccess.file_exists(p) and not _remove_file(p)`),返回 true、文件留盘。
- 推演:冒烟 ②段 `check(not FileAccess.file_exists(slot_tpl % 3) ...)` 直查文件系统 → 段内文件仍在 → 判红;`sv6 删非激活槽:文件不在盘` 同理红;⑥段 `delete_slot(3)` 后空槽窥视读到残file值 600 → `sv7 空槽窥视=零值合法态` 连带红。红集与报告变异表②一致,拦截面成立。
### ③ 测试削弱检查表(diff 全部删改逐处 vs 卡片 §7.2 申报)
| diff 改动处 | 定性 | vs §7.2 申报 |
|---|---|---|
| `smoke_all.gd` 删 5 行:V2d-1「boot 态==断点在档态」关系判据整块 | 既有断言改写(唯一一处) | **申报内**(§7.2 唯一允许面=boot 链 V2d-1)。判据**收紧非放宽**:原=关系判据 `visible == has_breakpoint`;新=钉死两事实 `not has_breakpoint() and not visible`。断言文本带「卡① sv2 改写」标识与「卡② mn8 再承接」注记,禁判据空转的条件满足。 |
| `save_manager.gd` 删 8 行:6 行注释+2 处生产代码(`_init` 默认参 `"user://save.json"`→`""`、`_ready` 删 `load_from_disk()`) | 生产改动本体 | 非断言删改;两处均=卡片 §7.1 sv2 行申报的改动本体(「_init 默认参取消」+启动态钉死),非测试削弱面。 |
| `smoke_all.gd` 其余 +176 行 | 纯新增(`_smoke_save_slots` 新段+V2-s1..s4) | 不属削弱面;既有段零触碰(game/ 删除行逐行清点:合计 13 行=上两行所列,无其他)。 |
| `run_all.gd` +3 行 | 纯新增三套件注册 | 既有注册零删改、顺序与 expect 域未动——无削弱。 |
**小结**:除申报内 V2d-1 改写外,diff 中不存在任何未申报的既有断言删改、阈值放宽、扫描面缩小或入口替换。
### ④ 回执核验(`game/tests/.gates/receipt.json`)
- `commit` = `074cfe27a4b4cc6c67d359c033729243e86ce4eb` == 分支尖 HEAD —— **一致**;
- `all_green` = **true**;`domain` = **"code"**(本批只碰 game/ 代码与断言面,选档正确);`quick_mode` = false(非快闸)。
- 闸明细:01 冒烟全量/02 单元套件/03 探针 --click/04 探针 --full/05 渲染闸/09 静态扫描/10 熵增闸均 green;`11 回放确定性对拍` = NEED-APPROVAL 未跑(`not_run` 在案;与卡片「MC 零跑、纯承载改造」口径相容,此处只记录不另裁);`inherited_red` 注记 09 静态扫描「基线红→现绿(改善)」。
- 审计对回执的独立支撑:冒烟 1201/0 与单元 38 套件全绿均为审计自跑复现(见文首基线)。
## 结论(首轮审计,盘面=074cfe27)——未通过(两缺漏已回炉,终审见文末复审小节)
首轮缺漏清单(保留存档,回炉事实见复审小节):
1. **sv3(必回炉,缺漏)**:
- **撤销证明不成立(实测)**:拆除 `write_to_disk` 无激活闸后,单测 2 条断言+冒烟 V2-s3 全部仍绿——拒写断言锚在返回值 false,与空路径下游写失败不可区分;拆闸运行实测在项目根落杂散 `.tmp`(写盘真实发生),而「盘面零触碰」断言只扫三槽路径,抓不到该副作用通道。报告 sv3 行「撤销=去掉判定 → 拒写断言红(代码评审可证)」经实验推翻,变异记录表亦无此条实测。
- **申报真实入口零对照面**:卡片与报告均申报真实入口=`MetaProgression.settle_adventure()`(`meta_progression.gd:275`,写盘 :282)链触达写盘被拒,但两个测试落点均裸调 `write_to_disk`(单元类级+真实 autoload 直调),无任何 MetaProgression 链在无激活态下触达写盘的断言。
- 回炉方向(供实现段参考,非裁断):断言加掃描空路径写失败的实际副作用面(如杂散 .tmp 不在盘),并补一条 MetaProgression 链(或等价生产链)无激活触达写盘被拒的断言;补做拆闸变异实测留红。
2. **sv4(须回炉,缺漏·轻)**:申报变异「新档写成读旧档」未执行,且在现有冒烟段序下(②段先删槽 3、③段才新档)无判别力——读旧档变体读到空档=默认态,全零断言仍绿;报告以推理代实测且未按 test-conventions §6 降格标注「已实现,拦截能力未证」。回炉方向:新档断言前预置带异值的残档夹具(或调整段序),补做该变异实测留红;或按 §6 如实降格标注。
其余 sv1/sv2/sv5–sv14 共 12 行逐行**通过**(其中 sv8/sv9/sv12 的变异为审计静态推演补证、sv11/sv12 附注见逐行表);测试削弱检查无未申报删改;回执三项核验全过。首轮审计未合并任何提交、未改 `game/` 下任何文件(两处变异注入均已 `git checkout` 精确还原,审计产物杂散 `.tmp` 已删,`git status` 干净)。
## 复审(2026-10-21,回炉提交 4a8558a0)
**回炉 diff 核验**(`git diff 074cfe27..4a8558a0`,仅两测试文件+实现报告对账,生产代码 `game/core/` 零触碰):
- `save_boot_no_activate_test.gd` 8→12 检查,**纯新增**(删除行逐行清点=仅 3 行文件头注释,零既有断言删改):②段加「拒写退化写目标零触碰」锚——空 `_path` 派生的裸 `.tmp`/`.tmp.tmp` 夹具清场后断言零新增(正是首轮拆闸实验实测的杂散落点通道);新增 ③段 `_test_settle_chain_write_rejected`:真表 ConfigDB+`MetaProgression.settle_adventure` 生产链全段驱动(`mark_first_adventure_done`→`apply_adventure_summary`→`refresh_treasure_unlocks`→`write_to_disk`),断言落账内存(adventure_total=1)而写盘无目标+链触达后退化写目标零新增——首轮「生产链零对照面」缺漏的对照面成立,卡片 sv3 申报真实入口自此有机检面。
- `smoke_all.gd` ③段**段内改写**:`create_slot` 前预置非白板 v7 旧内容(keystone 999/adventure_total 5/adventure_cleared 2);白板断言加 `adventure_total()==0` 合取项;旧「文件在位」检查升格为「盘面文件内容核验非 999」(解析落盘文件取 `keystone_balance==0`——文件缺失或不可解析时哨兵 -1 必红,存在性被其子集化)。两处被换断言均系本批新增断言(非卡片 §7.2 辖区的批前既有断言),且为升格收紧非放宽;段内检查数 3→3,冒烟总数保持 1201。
- 实现报告 sv2/sv3/sv4 行与变异表补⑥⑦两行对账更新,sv3 行撤销主张改写为实测执行——与审计实测结果一致。
**复审自跑实录**(命令同首轮;每次变异后 `git checkout -- game/core/save_manager.gd` 精确还原并确认 `git status --porcelain -- game/` 为空):
- 基线:`save_boot_no_activate_test.gd` → **all green (12 checks)**;单元全量 `run_all.gd` → **38 套件全绿**;全量冒烟 → **1201 项 / 0 失败三闸过**(回炉后基线独立复现)。
- **变异⑦复现**(=首轮审计的拆闸实验原样重放):`write_to_disk` 闸改 `if false and _path == ""` 注入 → boot 套件**恰两锚红**——「sv3 拒写退化写目标零触碰(裸 .tmp 零新增——拒绝口可判别锚)」+「sv3 生产链盘面:结算触达后退化写目标零新增(链上真实入口的盘面核验)」,且杂散 `.tmp`(845 字节,链上结算落账数据)真实落盘被两锚抓获 → 还原清理 → 复跑 **all green (12 checks)**。首轮「拆闸不红」的缺漏自此闭合。
- **变异⑥复现**:`create_slot` 内 `_data = _default_data()` 改 `load_from_disk()`(读旧档)注入 → 全量冒烟**恰 sv4 两行红**——「sv4 新档=全零可玩合法白板态(旧内容 999/5 零带入)」+「sv4 新档落盘=白板内容(盘面核验非 999 旧值)」,1201 项 2 失败 → 还原 → 复跑 **1201/0 全绿三闸过**。sv4 盘面核验断言「真能抓读旧档」经**实测**证实(非静态推演),与报告变异表⑥逐行一致。
- 回执核验(复审轮,盘面刷新件):`receipt.json` `commit`==`4a8558a0`==HEAD、`all_green`=true、`domain`="code"、`quick_mode`=false;`not_run` 同首轮(11 回放确定性对拍 NEED-APPROVAL,记录不另裁)。
**复审削弱检查**:回炉 diff 删除行逐行清点=boot 套件 3 行文件头注释+smoke ③段 1 行注释与 2 行本批新增断言;零批前既有断言删改、零阈值放宽、零扫描面缩小、零入口替换——**未引入新的未申报削弱**。
**复审判定**:sv3、sv4 两缺漏回炉后断言均经实测具备判别力(变异⑦/⑥注入见红、还原复绿),sv3 申报真实入口已有生产链对照面(链级断言实测在役),处置未引入新削弱——两行改为**通过**。
## 结论(终审)
**通过**——sv1–sv14 全部 14 行通过(sv3/sv4 回炉后复审通过,凭据见复审小节;首轮未过记录保留于上,回炉事实=提交 `4a8558a0`)。独立验收审计合并前置达成。复审全程零 commit、`game/` 零残留(两处变异注入均已精确还原,杂散件已清)。