diff --git a/reports/iter33-验收审计-2026-10-21.md b/reports/iter33-验收审计-2026-10-21.md index f09af3a6..0740af9f 100644 --- a/reports/iter33-验收审计-2026-10-21.md +++ b/reports/iter33-验收审计-2026-10-21.md @@ -1,7 +1,7 @@ # 迭代 33 独立验收审计(2026-10-21) > 审计人:未参与实现的独立会话,只采信盘面证据与自跑实测,不采信任何报告的「已全绿」。 -> 被审计对象:卡① 存档制数据层改造批(worktree `D:\code\g-plan2-iter33card1-save`,分支 `iter33-card1-save`,实现提交 `6a7c2575`+`074cfe27`,基线 `7280070f`;首轮审计后回炉提交 `4a8558a0`,见文末复审小节)。 +> 被审计对象:卡① 存档制数据层改造批(worktree `D:\code\g-plan2-iter33card1-save`,分支 `iter33-card1-save`,实现提交 `6a7c2575`+`074cfe27`,基线 `7280070f`;首轮审计后回炉提交 `4a8558a0`,见文末复审小节)。卡③ 选档界面新建批审计见文末「卡③」节(worktree `D:\code\g-plan2-iter33card3-saveselect`)。 > 审计材料:需求卡片 §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 检查全绿**——均为审计自跑实测,见复审小节。 @@ -92,6 +92,100 @@ **复审判定**:sv3、sv4 两缺漏回炉后断言均经实测具备判别力(变异⑦/⑥注入见红、还原复绿),sv3 申报真实入口已有生产链对照面(链级断言实测在役),处置未引入新削弱——两行改为**通过**。 -## 结论(终审) +## 卡① 结论(终审) **通过**——sv1–sv14 全部 14 行通过(sv3/sv4 回炉后复审通过,凭据见复审小节;首轮未过记录保留于上,回炉事实=提交 `4a8558a0`)。独立验收审计合并前置达成。复审全程零 commit、`game/` 零残留(两处变异注入均已精确还原,杂散件已清)。 + +## 卡③ 选档界面新建批(3 存档位 · 新档/进档/删档) + +> 审计人:同一独立协议(未参与实现、只采信盘面证据与自跑实测、不采信报告「已全绿」)。 +> 被审计对象:worktree `D:\code\g-plan2-iter33card3-saveselect`,分支 `iter33-card3-saveselect`,实现提交 `a6614a3b`+`52dd1ad2`+`54bde367`,基线 merge-base=`ebf40947`(卡① 合并态)。 +> 审计材料:卡③ 需求卡片 §7.1/§7.2/§2 T0 对齐附注、实现报告卡③ 节(对照表+变异表十条+confirm 断言面清点)、`git diff ebf40947..HEAD`、三探针新段、闸回执。 +> 审计自跑基线(HEAD=54bde367):冒烟 **1201/0 三闸过**;单元 **38 套件全绿**;探针三件 exit=0(struct **PASS 全屏结构断言零红**/click **问题=0**/flow **PASS**);ui_contrast_probe **PASS(38 对测点)**;卡① `save_slot_summary_test` **12 检查全绿**(has_file 向后兼容面)。 + +### ① 逐行核对表(sl1–sl14,对实现报告实际对照表逐行复核) + +| # | 判定 | 依据(审计自查实录) | +|---|---|---| +| sl1 三槽呈现 | 通过 | `ui_struct_probe` 选档段+`_save_select_contract` 在盘:槽卡行数==3+`_count_scroll` 零滚动容器断言;〔sl1〕grep 命中。真实入口=`main._open_save_select()` 函数直调——**中间态登记核实**:实现报告「已知中间态」#1+对照表 sl1/sl5–sl7 真实入口列均在案;全仓 `_open_save_select` 调用方=探针 6 处+定义 1 处,生产零调用、无死钮预埋(「进入存档」钮属卡② mn3,本批未提前接线)——合法中间态成立。变异m7(ScrollContainer)注入点与红项(滚动计数+zero_size 结构族)桌核自洽。 | +| sl2 摘要三项逐槽读数 | 通过 | struct 段夹具按槽直写(槽1=钥石 555/通关 2 局/冒险 7 局)逐字断言+钥石徽全树枚举;真实入口=开层后渲染面 label 实取值。变异m2(`_save_select_data` 改读激活位)桌核自洽:槽1 两断言(摘要行+钥石徽)必红。 | +| sl3 摘要禁项 | 通过 | 禁词表=断点/种子/继续/停点/「 关」(label 全集 `contains` 扫描——「通关」无空格不误伤,词形注记在案);变异m9 双红记录(sl2 精确匹配+sl3 禁词)与词形表强化历史自洽(首轮缺「 关」被变异暴露后补齐=收紧)。 | +| sl4 空/有档操作集二分 | 通过 | **渲染面实测**:`_collect_button_texts` 逐行枚举 visible Button 文本(行1=进档+删档零新档;行2/3=仅新档零进档删档含置灰形态)+簿记 occ 判定保留;变异m3 **审计实测复现**(详②-1)。 | +| sl5 空槽新档链 | 通过 | click 段真实按钮信号路径(`new_btn.pressed.emit()`):active==1+槽1 白板落盘(盘面解析 keystone==0)+逐帧采样;中间态登记同 sl1。撤销机理成立(去 `create_slot` 调用→激活/落盘断言红)。 | +| sl6 有档槽进档链 | 通过 | click 段槽2 进档→active==2+落点营地层可见+选档隐藏。变异(进档读成当前激活槽)桌核自洽:active 断言红。 | +| sl7 删档二次确认链 | 通过 | 双路径全链:一击只开窗(`is_open`+文件在盘)→取消只关窗文件仍在(含消费方状态量清零)→再开窗确认删+槽回空+就地刷新(occupied_flags 翻转断言);变异m1 **审计实测复现**(详②-2)。 | +| sl8 消费方编排机制 | 通过 | 分派单口三断言(取消后/确认后 `_confirm_consumer` 清零+删档确认不误触发开局 `run_scope.is_adventure`);现役断点确认段(`ui_click_probe.gd:604` 起,行号较申报漂移)零改写复跑绿=new_adventure 侧活体回归;变异m4(confirmed 再连 `_start_adventure`)桌核自洽。生产接线核验:`_start_adventure_from_menu` open 前设消费方、`_on_confirm_accepted` match 路由、旧双常驻静态接线撤除(diff 删除行=申报的生产改动本体)。 | +| sl9 重启不预选(Q1 甲) | 通过 | struct 段开层前 `active_slot()==0` 断言+「已选」标记文本零命中+视图零选中态字段(文件核);boot 级由卡① V2-s1 承接。变异m8(预选标记)桌核自洽。 | +| sl10 返回路径与 ESC 语境 | 通过 | `screen_flow_probe` 新步:返回钮真实信号→选档隐藏+开始层恢复断言+屏级互斥采样;合成 ESC 键(viewport.push_input)层不关断言。变异m5(只隐不关)与 m-ESC(加 ESC 处理)桌核自洽(申报已执行)。 | +| sl11 层序与模态纪律 | 通过(无新码尾缀——申报形态=既有段复跑,同卡① sv11 先例) | 凭据:`LAYER_CONTRACT` 加行+`_layer_node` 查表+构造三处在 diff 核实;`ui_struct_probe` 全屏 PASS 含 `_modal_registry_contract`(登记序==合同序,新层在册);冒烟 1201/0(V1d 源码合同段,审计自跑);ui_tune_probe 树序断言(:52 原样在位)经回执 04 --full 绿。变异(视图散落 move_child→V1d 判红)为既有闸机理,无新断言需变异。 | +| sl12 动线序不回闪 | 通过 | 逐帧三断言(落点帧选档隐藏/营地层可见/开始层保持隐藏)+**栈遮挡记账判别**(select ∈ `camp._occluded`);变异m6 红项与报告一致。强化历史核实:首轮帧采样对 m6 零红(close-then-open 形态在帧采样下不可判别)→52dd1ad2 **纯新增**记账断言(帧采样保留零删)——收紧非放宽。 | +| sl13 零新素材零新色值(非行为改动) | 通过(件核+复跑) | diff 核实:新视图文件零 `Color8(`/`Color(`/`preload`/素材路径,main.gd 新增行零色值素材(grep 计数=0);ui_contrast_probe **PASS(38 对测点+裸色白名单/preload 红线静态段绿)**(审计自跑)。无新码尾缀=件核行申报形态(同卡① sv13 先例)。 | +| sl14 反哺点清单(非行为改动) | 通过 | `reports/iter33-反哺点-2026-10-21.md` 卡③ 节 4 条(#7 生涯.md 结构树补层/#8 08 增行请求-明示须用户裁/#9 待办清单+roadmap 推进/#10 存档序列化消费面纪律补 has_file 口径)覆盖卡片 §5 全部落点。 | + +### ② 撤销/变异证明抽查记录(审计自跑实测) + +**②-1 变异m3 复现(空槽渲染删档钮——按簿记缝盲区形态注入:渲染但不注册簿记字典)** +- 注入:`save_select_overlay.gd` `_build_slot_row` 空槽分支尾加 `row.add_child(UiKit.danger_button("删档", "MUTATION m3"))`(不写 `_delete_btns`)。 +- `ui_struct_probe` → **exit=1,恰两行红**:「行2 操作集失守(空/坏槽应=仅新档、零进档删档含置灰形态)〔sl4〕」+「行3 ……〔sl4〕」——首轮走簿记缝的盲区(字典未含该钮)被渲染面扫描闭合,实测证实强化有效。 +- `git checkout --` 还原 → 复跑 **PASS 全屏结构断言零红** → `git status` 干净。 +- 强化本身核查(52dd1ad2 diff 逐行):sl4 由簿记字典缝改为真实钮文本枚举(扫描面扩大、occ 簿记保留、零检查删除);sl3 词形表扩充;sl12 记账断言纯新增——**未引入未申报削弱**。 + +**②-2 变异m1 复现(删档直连删除,跳过确认窗)** +- 注入:`main.gd` `_on_save_select_delete` 改直连 `save_manager.delete_slot(slot)`+就地刷新,原确认链 `if false` 短路。 +- `ui_click_probe` → **exit=1,sl7 面如期红**:「sl7 一击未只开确认窗(直删形态)」。同轮另现一条连带红「断点段:战败结算后断点未清」——该段在变异前基线与还原后复跑均 0 红,判为变异扰动的对局段偶发(预算帧漂移 9781→9749→6619),非基线不稳,记录备查。 +- 还原 → 复跑 **问题=0** → `git status` 干净。 + +**②-3 变异表十条逐条桌核**:m1/m3 实测如上;m2(读激活位→sl2 两断言红)、m4(双常驻接线→`run_scope.is_adventure` 红)、m5(只隐不关→恢复断言红)、m6(先关后开→记账判别红,帧采样不可判别的机理说明与 ModalStack 语义核实一致)、m7(ScrollContainer→滚动计数+zero_size 结构族双红)、m8(预选标记→文本命中红)、m9(拼关数→sl2+sl3 双红)、m-ESC(ESC 关层红)——注入点、断言面、红项记录逐条与盘面代码对得上,自洽。 + +### ③ 测试削弱检查表(diff 全部删改逐处 vs 卡片 §7.2 申报) + +| diff 改动处 | 定性 | 判定 | +|---|---|---| +| `smoke_all.gd` | **零改动**(del=0/add=0) | 与对照表「卡③断言全在探针层,冒烟零新增」一致 ✓ | +| `ui_struct_probe.gd`/`ui_click_probe.gd`/`screen_flow_probe.gd` | **纯新增**(del=0;+103/+96/+41) | 既有段零触碰 ✓;批内强化提交 52dd1ad2 为批内新断言的演进(m3/m9/m6 盲区修正),全部收紧零删(详②-1) | +| §7.2 申报四位点(按内容定位,行号已漂移) | 逐一核实 | `ui_struct_probe` confirm 结构采样(:103-106)、`smoke_all` `_topmost_visible_layer` 候选表(:226 区)、`ui_click_probe` 断点确认交互段(:604-623)、`ui_tune_probe` 树序断言(:52)——**全部原样在位零改写**(申报允许改写而实际未改,优于申报) | +| `main.gd` 删 9 行 | 生产改动本体 | 旧双常驻静态接线(`_on_confirm_new_adventure`/`_on_confirm_cancelled` 及两条 connect)撤除=卡片契约 3/§9 第 6 条+sl8 申报的改动本体,非断言削弱;新分派行为与旧 handler 逐句等价(new_adventure 分支对照核实) | +| `save_manager.gd` 删 4 行 | 接口补全 | 注释 2 行+peek 返回字典字面量 2 处加 `has_file` 键——向后兼容扩展,卡① 断言零触碰(详⑤) | + +**小结**:零未申报削弱;零批前既有断言删改;零阈值放宽;零扫描面缩小;零入口替换。 + +### ④ 回执核验(`game/tests/.gates/receipt.json`,盘面工作件) + +- `commit` = `54bde3678ab8707872c2a117d75e7a9e8abcb91f` == HEAD ✓;`domain` = "code" ✓;`quick_mode` = false;`not_run` = 11 回放确定性对拍(NEED-APPROVAL,同卡① 口径)。 +- **`all_green` = false ✗**:`09 静态扫描` exit=1,且 `changed_vs_baseline` 记录红项清单较基线变化(基线 4354b2aa72a7 → 现 2b71884ec242;卡① 合并态该闸为绿/改善,存量基线记录的旧红清单已被卡① 清零)。其余 01 冒烟/02 单元/03 探针 --click/04 探针 --full/05 渲染闸/10 熵增闸 green(其中 01/02/03+struct/flow/contrast 探针经审计自跑复现)。 +- 审计现场复现红项:`python tools/audit_type_hints.py` → **存量 2 处 R1(裸 Dictionary/Array 注解)**——`main.gd:1176`(`var p: Dictionary`,`_save_select_data` 内)+`save_select_overlay.gd:58`(`var slots: Array`);两处均为卡③新增代码行(diff `+` 行核实),即本批新引入的类型闸红。 +- **与实现报告矛盾**:卡③ 状态行与读数对照声称「批末重闸 --code 全绿(回执见合并提交信息)」——盘面回执 `all_green=false` 且红闸为本批新引入,报告表述失实。按硬性红线「`run_all_gates.sh` 所选域全绿才合回 master」,本批当前态**不可合并**。 + +### ⑤ has_file 接口补全专项 + +- diff 核实:`save_manager.gd` 仅 4 删 6 增=窥视读器注释改写+peek 返回字典(越界分支与 `out` 初始化)加 `has_file` 键+主文件在盘置位一行——**纯返回键扩展,向后兼容**。 +- 卡① 侧断言零触碰:`save_slot_summary_test.gd` 零 diff;审计直跑 **all green (12 checks)** ✓。 +- 三处留痕一致:卡③ §2 T0 对齐附注(has_file=空/有档操作集二分判定来处、非摘要第四项、零 UI 语义)=实现报告已知中间态 #4=追认单卡③ #7(列为待追认单项、veto 影响写明)——三处口径逐字一致 ✓。 +- 消费面核验:`_save_select_data` `occupied = has_file ∧ readable`(Q2 甲坏槽按空呈现)✓;视图零自判(槽态唯一来处=喂入数据)✓。 + +### 卡③ 结论(首轮)——未通过(已回炉,终审见文末卡③复审小节) + +**首轮缺漏清单(1 项,阻塞合并;保留存档)**: +1. **批末重闸未全绿+报告失实**:回执 `09 静态扫描` 红(2 处 R1 类型闸存量,均在卡③新增代码行:`main.gd:1176` 裸 `Dictionary`、`save_select_overlay.gd:58` 裸 `Array`;红项清单较基线变化),`all_green=false`;实现报告「批末重闸 --code 全绿」与盘面矛盾。回炉方向(供实现段参考,非裁断):两处容器注解参数化(如 `Dictionary[String, Variant]`/`Array[Dictionary]`)或按闸机规程报用户裁;重跑批末重闸取全绿回执(回执 commit 须对新 HEAD);更正实现报告「全绿」表述按盘面实况。回炉后按本协议复审。 + +其余全部通过:sl1–sl14 逐行核对 14 行通过(含中间态登记与无死钮核实、has_file 专项、三处留痕一致);变异 m1/m3 实测复现红→还原→绿,十条变异表自洽;52dd1ad2 强化纯收紧未引入削弱;§7.2 四位点零改写;smoke_all 零改动。审计全程零 commit、`game/` 零残留(两处变异注入均已 `git checkout` 精确还原)。 + +### 卡③ 复审(2026-10-22,回炉提交 b673ced) + +**回炉 diff 核验**(`git show b673ced`,仅两处代码修+实现报告更正,共 5 增 4 删): +- `main.gd:1176`:`var p: Dictionary = save_manager.peek_slot_summary(i)` → `var p := save_manager.peek_slot_summary(i)`(推断形态,行内注记写明取舍依据:裸注解触 R1、参数化 `Dictionary[String, Variant]` 赋值被运行期严格类型拒——实测 SCRIPT ERROR 实证过)。变量仍持同一窥视返回 Dictionary,下游 `.get()` 消费零变化。 +- `save_select_overlay.gd:58`:`var slots: Array = ...` → `var slots: Array[Variant] = []`+`slots.assign(data.get("slots", []))`(typed 容器纪律)。`assign()` 逐元素拷贝后迭代内容不变,`for sd: Dictionary in slots` 原样——零行为改动。 +- 两处均为审计申报缺漏的定点修除,容器注解形态变化(声明面),零逻辑改动——无未申报削弱可言(行为不变佐证:sl2 摘要读数断言、sl5/sl7 数据链断言复审全绿,见下)。 +- 实现报告更正核实:卡③ 状态行改为两轮记录(首轮未过原因含「收口时点只核回执 commit 未核 verdict」的流程订正);读数表「重闸 --code」行改为「首轮 all_green=false(R1×2 新增)→ 回炉后全绿」——首轮审计指出的「报告失实」已消除。 + +**复审自跑实录**(HEAD=b673ced): +- `python tools/audit_type_hints.py` → **PASS,产品码类型闸归零(R1/R2/R3)**,exit=0(首轮红项 `main.gd:1176`/`save_select_overlay.gd:58` 均已消)。 +- `ui_struct_probe` → **PASS 全屏结构断言零红**——含 sl2 摘要读数断言(555/2 局/7 局逐字)绿=`_save_select_data` 改推断形态后喂入数据面零行为变化的实测佐证。 +- `ui_click_probe` → **exit=0,问题=0**——sl5/sl7 数据链与 `open_save_select` 的 `Array[Variant]`+`assign()` 消费面(每次开层走该口)零行为变化的实测佐证。 +- 回执核验(复审轮):`commit`==`b673cedd…`==HEAD ✓、`all_green`=**true** ✓、`domain`="code" ✓、`quick_mode`=false;`09 静态扫描` exit=0 green(fingerprint green)——首轮红闸闭合;`not_run` 同前(11 回放确定性对拍 NEED-APPROVAL);回执时间戳(06:11:28)在回炉提交(06:04:59)之后=修后重闸实测。 + +**复审判定**:缺漏 1(批末重闸未全绿+报告失实)回炉后闭合——类型闸归零、回执全绿且对上 HEAD、报告更正为两轮实况。零未申报削弱。卡③ sl1–sl14 全部 14 行通过。 + +### 卡③ 结论(终审) + +**通过**——卡③ 选档界面新建批 14 行(sl1–sl14)全部通过(首轮未过记录保留于上,回炉事实=提交 `b673ced`)。独立验收审计合并前置达成。复审全程零 commit、`game/` 零残留、`git status` 仅本报告工作件。