docs(独立验收审计): 审计判定可合并+八项处置全部落笔
- 新增 reports/iter37-验收审计-四卡-2026-10-25.md(未参与实现的独立子代理,273 行;四卡对照表逐行核对+测试削弱 24 行删除逐条归位零削弱+卡④ 等价性机检逐表达式对拍+实跑复现卡④ P-B 撤销证明并还原复绿) - F-1 卡② r1-1 真实入口更正为探针开层链与组合根直引,如实记三件至今无单元级断言 - F-2 卡④ 委托与 const 行号指针订正、契约 5 入口去掉下层直调冒充(改指 level_shop_economy_test:1251 真链) - F-3 补代拍板 B-8:卡③ 查表族与墨族表驱动化重构(为压 S13 函数阈值,等价已由审计穷尽验证),此前漏报 - F-5 卡②③ 逐字迁移核对交付物指回审计 §2.2/2.3/5.5 并补实现报告 §3.1b - F-6 读数表列名改「卡片成文读数预期」,main 判超出卡面 424 行、board_view 判未达成超 57 行 - 新增披露三条:断点单源实际只对 9/27 键派生(hero_hp/bonus 名义 clamp 未派生)、双写面含生产续玩链、wr2 三条仅冻结清单承力 - F-4 行访问器直读与 ConfigDB 单点口径列反哺点第 9 条;F-7 卡片 spec-AC 矛盾退回上游;F-8 随复跑消解
This commit is contained in:
1 parent
356029d007
commit
9594363438
4 files changed
+309
-7
No files matched your search
@@ -13,6 +13,7 @@
|
||||
| B-5 | 卡④ `CurioDeck.reset()` **不清凭证三计数**(`ticket_pity`/`ticket_sold`/`ticket_appeared`) | 宿主原 `_reset_curio_state` 就只重置池与 kind 计数;清零会改限购/保语义=行为变更。等价性优先于"看起来更合理" | curio_deck.gd `reset()` |
|
||||
| B-6 | 卡① d18 参数注解形态:卡片字面 `lumas_out: Array[Variant] = null` 在 Godot 4.7 解析报错(typed array 不可默认 null),改用 `: Variant = null` | 唯一合法注法,零行为变化 | commit `0529e169` |
|
||||
| B-7 | 卡① T1 三处代拍板:`target_mine_count` 签名(照接口块)、信号契约措辞与载荷键并集(按发射位实查)、`int()` 读侧包裹写法 | 卡片白名单内预授权面 | commit `1b9736f0` |
|
||||
| B-8 | 卡③ r2-1 的**瓦片查表族与墨族判据改为表驱动重构**(16 掩码查表+`_family_contrasts`/`_mean_of` 辅助式),非逐字迁移 | 独立验收审计 F-3 抓出本批漏报;动机=把 `wall_tile_for`/`wall_center_tile`/`digit_ink_mode` 从 S13 函数级超标(分支 14/返回 15/局部 12)压回阈值内,兑现「只改代码不改基线」;等价性由审计穷尽验证(掩码/档位/三态真值表零差)+golden 三图 0.00%。**违卡③ 契约 1「禁顺手改算法」字面,未违语义**——请追认;不回退 | commit `5c9c5f80`+实现报告 §3.1b |
|
||||
|
||||
## 二、认错(会话处置错误,已补账)
|
||||
|
||||
|
||||
@@ -44,6 +44,12 @@
|
||||
- **改成什么**:加一条判据——「重构类需求卡片必须写明:**禁止为迎合机检消息文本(含计数)而保留或新增无效成员/别名**;遇机检键与卡片契约互斥,实现段一律停卡呈报,不得自造第三条路」。
|
||||
- **依据**:本批 E-1 实证——卡片契约 1「公开面零变化」×旧基线键含计数=数学上只剩"持平/达标/停卡",实现段自拍糊数即违实现段零裁断。规则修订须先在真实任务上评估(本条已评估:本批三处踩同一坑)。
|
||||
|
||||
## 9. 单点读取口径需核一次:行访问器直读是否等同「ConfigDB 单点」
|
||||
|
||||
- **文件/节**:[design/engineering/code-conventions.md](file:///D:/code/g-plan2/design/engineering/code-conventions.md) 数值单点纪律条(+AGENTS.md 同一条红线)
|
||||
- **改成什么**:明确「经 `db.shop.relic_base_price` 这类**表行访问器**直读」是否满足「玩法数值只存 .tres 经 ConfigDB 单点读取」。本批 `2ed81668` 退役了 `ConfigDB.shop_relic_base_price()`/`shop_spend_discount()`/`hero_display_name()` 三个包装访问器,消费面改直读行访问器(理由=配置值写死进代码再运行时追加=双重真值);独立审计 F-4 指出该改法与卡片钉值表文本不一致,需口径裁断而非默认放行。
|
||||
- **依据**:审计 F-4;commit `2ed81668`;代拍板单 F-4 行。
|
||||
|
||||
## 8. 观感/交互类无(本批零行为变更)
|
||||
|
||||
本批四卡全部为缺陷定点修+等价重构,无 GDD 数值与玩法语义变化;数值表新增两 knob(`relic_base_price`/`spend_discount`,卡① d11)与 `display_name`(d16a)已随卡① 提交入库,其**表值即事实源**,GDD 若已列同值则无需改动——文档批按现行 GDD 核一次即可,未核前不落笔。
|
||||
@@ -13,10 +13,10 @@
|
||||
|
||||
## 1. 完成定义读数(卡片「读数项非停机闸」如实申报)
|
||||
|
||||
| 件 | master | 本批 HEAD | 卡片预期 | 达成 |
|
||||
| 件 | master | 本批 HEAD | 卡片成文读数预期(非停机闸) | 达成判定 |
|
||||
|---|---|---|---|---|
|
||||
| `main.gd` | 1506 | **946** | ≤999(S13 文件线) | 达成 |
|
||||
| `views/board_view.gd` | 1219 | **937** | ≤1000 | 达成 |
|
||||
| `main.gd` | 1506 | **946** | ≈1370–1380(卡② §1 成文读数预期) | **超出卡面 424 行**(代拍板 B-2 扩面所致,非 r1 清单量;卡② 自注「读数项非停机闸,判离量以函数清单为准」);S13 文件线 ≤1000 另达成 |
|
||||
| `views/board_view.gd` | 1219 | **937** | ≈880(卡③ §1 成文) | **未达成**(超 57 行=13 条转发属性+常量别名回填 ≈70 行);S13 文件线 ≤1000 达成 |
|
||||
| `core/adventure_runner.gd` | 1050 | **989** | ≈850±10 | **未达成**(−61;委托层注释、`BREAKPOINT_FIELDS` 登记段与六小函数回填 ≈150 行,抵掉迁出 ≈183 行。公开面冻结+停点编排留宿主使迁出面本就 ≈183 行,卡片 850 预期系按 v1.0 旧边界算,读数项非停机闸) |
|
||||
| `core/level_runner.gd` | 999 | **857** | ≈780 | **未达成**(−142;17 个同签名委托+2 个私有委托+8 条转发属性回填 ≈70 行) |
|
||||
| 新件 `core/curio_deck.gd` | — | 259 | — | 净增 |
|
||||
@@ -55,7 +55,7 @@
|
||||
|
||||
| 单元 | 落点(实际) | 真实入口断言 | 撤销证明 |
|
||||
|---|---|---|---|
|
||||
| r1-1 数据投影五函数出根 | presentation/hud_presenter.gd 静态族(status_data/status_curios/career_data/save_select_data/camp_data) | hud_presenter_test+ui_struct_probe 直调面 | 删承接体 → Parse Error 红→还原复绿 |
|
||||
| r1-1 数据投影五函数出根 | presentation/hud_presenter.gd:230/:245/:257/:280/:293 静态族(status_data/status_curios/career_data/save_select_data/camp_data) | **真实入口=探针开层链**:ui_struct_probe.gd:60/:94 与 ui_click_probe.gd:789 经 main 薄委托(main.gd:317/main_overlay_flow.gd:25/:39/:57/:133 直引 HudPresenter.*)。**如实更正(审计 F-1):hud_presenter_test 零引用这五个静态件,`career_data`/`save_select_data`/`bonus_summary_text` 至今无单元级断言**,建回归断言属下一批 | 删承接体 → Parse Error 红→还原复绿 |
|
||||
| r1-2 只读解析回调四函数 | **新件** presentation/board_resolvers.gd(db+浮窗+结算三参注入) | ui_click_probe/system_test 棋盘读数面 | 撤销注入 → 解析 Callable 断言红 |
|
||||
| r1-3 文案拼装三件 | hud_presenter.gd(gp_summary_text/bonus_summary_text/phase_text) | pacing_queue_test/player_copy_sweep | 删 `gp_summary_text` 承接体 → Parse Error+error_scan exit 1 红,还原复绿(**在案那条**) |
|
||||
| r1-4 探针直引零改动 | main.gd `_camp_data`/`_status_data`/`_gp_summary_text` 三薄委托 | 探针原签名直调 | 等价申报(委托层零语义) |
|
||||
@@ -73,10 +73,10 @@
|
||||
|
||||
| 单元 | 落点(实际) | 真实入口断言 | 撤销证明 |
|
||||
|---|---|---|---|
|
||||
| r3-1 令牌池与判定出根 | **新件** core/curio_deck.gd(259 行:`build/reset/token_identity/find_token/pool_stock/stock_snapshot/consume_deck_token/consume_pool_purchase/cap_ok/feat_ticket_consider/draw_candidates`);宿主 10 个同签名委托(adventure_runner :355/:443/:457/:465/:471/:641/:647/:654 等) | adventure_feats_test 138 项/pool_case_d 17 项/feat_vouchers 49 项/curio_refresh_paid 21 项/level_shop_economy 186 项(全部经 `start_adventure`→真链进入) | **P-C**:`_find_token` 委托体回退成 `return {}` → adventure_feats_test 成片红(「通关三选一恰呈现 2 次、恰兑付 2 次」等 6 条),还原复绿 |
|
||||
| r3-1 令牌池与判定出根 | **新件** core/curio_deck.gd(259 行:`build/reset/token_identity/find_token/pool_stock/stock_snapshot/consume_deck_token/consume_pool_purchase/cap_ok/feat_ticket_consider/draw_candidates`);宿主 8 个同签名委托(adventure_runner 实址 :357/:444/:456/:461/:466/:635/:640/:645)+4 条转发属性 getter(:61/:64/:73/:76) | adventure_feats_test 138 项/pool_case_d 17 项/feat_vouchers 49 项/curio_refresh_paid 21 项/level_shop_economy 186 项(全部经 `start_adventure`→真链进入) | **P-C**:`_find_token` 委托体回退成 `return {}` → adventure_feats_test 成片红(「通关三选一恰呈现 2 次、恰兑付 2 次」等 6 条),还原复绿 |
|
||||
| r3-2 商店族出根 | **新件** core/shop_session.gd(339 行,21 函数同形);level_runner 17 公开委托+2 私有委托(`_spend_discounted` :801、`_shop_draw_shelf` :812,测试直引面保号) | level_shop_economy_test/meta_progression_forge_test(`lr._spend_discounted(100)==80` 走件内折价) | **P-A**:`pool_price` 委托体回退成 `return -1` → `[FAIL] relic 现价 = ceil(15.0×b^(关序−1))…〔wd11〕` 红,`git checkout --` 还原后 186 检查复绿 |
|
||||
| r3-3 断点字段登记单源 | adventure_runner :857 `const BREAKPOINT_FIELDS`(27 键)+写侧 `_bp_parts()` :909 +读侧 `_bp_read`/`_bp_strategy`/`_bp_read_int`;`resume_adventure` 由 108 行巨型体拆成六小函数(`_resume_ledger`/`_resume_curio_state`/`_resume_params`/`_resume_counters`/`_resume_pending` 及主体 36 行);二次消费面(`node_id`/`visited_ids`/`aux_items`)改走 `_bp_read` | **wr2 新增断言**:breakpoint_resume_test Part 8 三行——登记键集==写侧实拼键集、键集==冻结 27 键清单、策略标签全落六类词表〔wr2〕;主线回归=breakpoint_resume_test 59 项+iter36 wc2 续玩断言(ui_click_probe「续玩重建开场行带后缀 bonus.atk=5」) | **P-B**:从登记里删 `"refresh_stock"` 一项 → `[breakpoint_resume_test] FAIL — P8 键集与冻结清单逐位一致(27 键契约;增删键即红)〔wr2〕`(1/59 失败),还原复绿 |
|
||||
| 契约 5 必改接线行 | adventure_runner :745 `_runner.set_shop_pool(_curio_deck, _consume_pool_purchase, _feat_ticket_consider, _curio_cap_ok)` 四标识符改指委托/件读面,参数序不变 | pool_case_d_test 直调 `set_shop_pool` | 在 r3-1/r3-2 撤销证明覆盖面内 |
|
||||
| r3-3 断点字段登记单源 | adventure_runner :864 `const BREAKPOINT_FIELDS`(27 键)+写侧 `_bp_parts()` :907 +读侧 `_bp_read`/`_bp_strategy`/`_bp_read_int`;`resume_adventure` 由 108 行巨型体拆成六小函数(`_resume_ledger`/`_resume_curio_state`/`_resume_params`/`_resume_counters`/`_resume_pending` 及主体 36 行);二次消费面(`node_id`/`visited_ids`/`aux_items`)改走 `_bp_read` | **wr2 新增断言**:breakpoint_resume_test:191/:199/:206 三行——登记键集==写侧实拼键集、键集==冻结 27 键清单、策略标签全落六类词表〔wr2〕。**承力实测(审计):三条里只有「键集==冻结 27 键」在增删键时变红**,另两条因写侧与登记同源派生,删键时同步变化而不红;主线回归=breakpoint_resume_test 59 项+iter36 wc2 续玩断言(ui_click_probe「续玩重建开场行带后缀 bonus.atk=5」) | **P-B**:从登记里删 `"refresh_stock"` 一项 → `[breakpoint_resume_test] FAIL — P8 键集与冻结清单逐位一致(27 键契约;增删键即红)〔wr2〕`(1/59 失败),还原复绿 |
|
||||
| 契约 5 必改接线行 | adventure_runner :745 `_runner.set_shop_pool(_curio_deck, _consume_pool_purchase, _feat_ticket_consider, _curio_cap_ok)` 四标识符改指委托/件读面,参数序不变 | **真链**=level_shop_economy_test.gd:1251(经 start_adventure→关卡推进进店);pool_case_d_test:45 自构 LevelRunner 直调 `set_shop_pool`,属下层直调,**不算本行验收入口**(审计更正) | 在 r3-1/r3-2 撤销证明覆盖面内 |
|
||||
|
||||
**卡④ 撤销证明共三条**(P-A/P-B/P-C,各覆盖一单元),满足并超出卡片 T3「至少两条」。三条全为「回退本批 hunk → 断言红 → 还原复绿」,无注入式变异开关(用户 P0 令口径)。
|
||||
|
||||
@@ -88,6 +88,11 @@
|
||||
- **ShopSession**:21 函数同形;`set_shop_pool` 四参签名与缺省值 `Callable()` 逐字对齐(卡片 §103)。钱包与加算区经 `bind(refs, hooks)` 持**宿主对象引用**:`wallet`(`_ledger`)、`run_ledger`(账类,件内每次重读 `.bonus`,防宿主 `run_ledger.bonus = {...}` 换代失真)、`level_row`(原地 `assign`)、`tree_rules`/`attunement`;五个换代点全部重绑——level_runner :165/:205/:646/:670/:688 调 `_bind_shop()`。
|
||||
- **未迁面**:停点编排与兑付推进留宿主(`skip_empty_curio`/`pick_curio`/`_apply_curio_pick`/`_finish_curio_pick`/`present_node_curio`/`apply_node_curio`/refresh 族/`_redeem_feat_ticket`),断点五时点集零增减零迁移(A4 核:`:506/:634/:803` 现址仍在同三个函数体内)。
|
||||
|
||||
### 3.1b 卡②③ 逐字迁移核对(交付物补位,审计 F-5/F-3)
|
||||
|
||||
- **交付物指认**:卡②③ 的「逐函数:原行界→新落点→逐字差异」核对结果由独立验收审计机检补上,本批不再重复制表——见 [iter37-验收审计-四卡-2026-10-25.md](file:///D:/code/g-plan2-iter37/reports/iter37-%E9%AA%8C%E6%94%B6%E5%AE%A1%E8%AE%A1-%E5%9B%9B%E5%8D%A1-2026-10-25.md) §2.2(卡② 逐函数 diff 结论)、§2.3(卡③)、§5.5(查表族与墨族真值表穷尽验证)。
|
||||
- **须申报的偏差(审计 F-3,本批此前漏报)**:卡③ r2-1 的**瓦片查表族与墨族判据不是逐字迁移,而是表驱动化重构**——`wall_tile_for`/`wall_center_tile` 改 16 掩码查表、`digit_ink_mode` 改 `_family_contrasts`/`_mean_of` 辅助式。动机=把这三个函数从 S13 函数级超标(分支 14/返回 15/局部 12)压回阈值内,属"改代码不改基线"令的推论。**等价性**:16 掩码逐位、60/20/20 档、三态真值表由审计穷尽验证零差,棋盘 golden 三图 changed=0.00%。**处置**:不回退,补代拍板 B-8 追认(卡片契约 1 字面写「禁顺手改算法」,此项越字面但未越语义)。
|
||||
|
||||
### 3.2 断点 27 键单源对照表(改前读侧实义 → 改后策略标签,逐键一致)
|
||||
|
||||
| 键 | 标签 | 改前读侧实义(原 `resume_adventure`/二次消费) | 一致 |
|
||||
@@ -125,6 +130,9 @@
|
||||
5. **golden 基线换代**(用户裁「重制三张」):成因 `2f3a87e9` 与本批零因果,判失效依据与复闸读数在 commit `7389618f`。
|
||||
6. **待办清单.md 由本批直写**:属越批性质禁写面,用户本轮明示授权且仅限这一条登记(commit `84dc3e4b`)。
|
||||
7. **等价类单元撤销不红**(卡① d11/d14/d15/d16、卡②③④ 全部委托层):属预期,以等价断言+读数对拍承载,已逐行标注。
|
||||
8. **断点「单源」的覆盖面比标称窄(审计发现,此前未披露)**:27 键里读侧真正经 `BREAKPOINT_FIELDS` 策略派生的只有 9 键(keep_on_null 三键+clamp 四键中的 `vision_counter_used`/`refresh_stock`+params_fallback 一键+二次消费三键走 `_bp_read` 默认通道)。`hero_hp` 与 `bonus` 四子键**登记为 clamp 但实际钳制写在 `_resume_ledger`/`_resume_params` 体内**(bonus 子键就地 `maxi(0,…)`、hero_hp 越界钳制依赖 `effective_max_hp` 时机),未从登记派生;`keep_on_null` 的类型守卫也部分靠调用点自身 `is Dictionary`/`is Array`。语义逐键与改前一致(审计逐表达式对拍零差),但"改登记即改行为"这条只在 9/27 上成立——拆卡重裁 BreakpointSchema 时按此读数定边界。
|
||||
9. **双写面比此前申报的多**:除 §4 第 3 条列的三处测试直引外,**生产续玩链也经转发属性写件内状态**(`_resume_curio_state` 里 `_curio_taken[id]=…` 与 `_curio_deck = restored`)。它是单点存储(属性 setter 指回件内唯一份),非双源,但"件封装名义化"的范围因此比原报更大。
|
||||
10. **wr2 三条断言只有一条承力**(见 §2 卡④ r3-3 行内实测):键名增删由「键集==冻结 27 键清单」拦住;「登记键集==写侧实拼键集」与「策略标签落六类词表」结构上与登记同源,删键不红。契约 3 的「单源键集断言」实质由冻结清单承担。
|
||||
|
||||
## 5. 实机目检总清单(真人检测只登记不阻塞)
|
||||
|
||||
@@ -198,3 +206,17 @@
|
||||
| 10 熵增闸 | 图像越界 11 个,全在 `.iter37-logs/golden_diag/*.png` | **本批在途件**(黄金图诊断临时件落仓库根临时目录,未入库) | 处置完删除整个 `.iter37-logs/` 临时目录(取证读数已转录本附录) |
|
||||
| 08d 引用可核 | 红项 1=`design/gdd/systems/跨局循环/生涯.md:55` 指 `adventure_runner.gd:1007-1018`,目标现 989 行 | **本批引起**(adventure_runner 1050→989 使文档行号引用超界),但修复位在被批性质禁写的 `design/` | **待用户裁**:授权本批同步该行号(一处)/或由文档批落文(则本批无法清红)。其余八处同类漂移因同句带日期/退役说明自动降为建议级 |
|
||||
| 07 doc_link | 基线红 → 现绿 | 本批无关(合并 master 带入) | 记为改善,无需处置 |
|
||||
|
||||
## 附录 D:独立验收审计八项处置(审计文件=`reports/iter37-验收审计-四卡-2026-10-25.md`,判定「可以合并」)
|
||||
|
||||
| # | 审计事项 | 本批处置 | 落点 |
|
||||
|---|---|---|---|
|
||||
| F-1 | 卡② r1-1 真实入口指认不实(hud_presenter_test 零引用五静态件) | 已更正为探针开层链+组合根直引,并记「三件至今无单元级断言」 | §2 卡② 行 |
|
||||
| F-2 | 卡④ 委托/const 行号指针 8 处不准;契约 5 入口用下层直调冒充 | 委托行号订正为实址八条+四条 getter;`:857→:864`、`:909→:907`;契约 5 改指 `level_shop_economy_test.gd:1251` 真链,`pool_case_d:45` 降级为非验收入口 | §2 卡④ 行 |
|
||||
| F-3 | 卡③ 查表族/墨族表驱动化重构未申报(违契约 1 字面) | 补 §3.1b 逐字偏差说明+代拍板 B-8 追认;等价性采信审计穷尽验证与 golden 0.00%,不回退 | §3.1b/代拍板 B-8 |
|
||||
| F-4 | 卡① d11/d16a「ConfigDB 三访问器」被 `2ed81668` 撤销改直读行访问器 | 括注已在案(`2ed81668` 退役理由=运行时追加=双重真值);「行访问器直读是否等同单点口径」列反哺点第 9 条待文档批核 | §2 卡① 行/反哺点 9 |
|
||||
| F-5 | 卡②③ 缺逐字迁移核对表交付物 | 交付物指回审计 §2.2/§2.3/§5.5(本批不重复制表),并补 §3.1b | §3.1b |
|
||||
| F-6 | 读数表用机检线冒充卡片预期 | 列名改「卡片成文读数预期(非停机闸)」,main 946 判「超出卡面 424 行」、board_view 937 判「未达成(超 57 行)」 | §1 |
|
||||
| F-7 | 卡① §8.3「唯一既有测试改动」与 d2×契约 5 互斥(卡片自身 spec-AC 矛盾) | 不属本批可修:V4 换代只增强不放宽(审计证实);矛盾退回写卡段,列反哺点第 7 条 | 反哺点 7 |
|
||||
| F-8 | 回执钉 `9e3e2667` 落后 HEAD(纯 reports/ 追加) | 随合并 master 后的全量档复跑消解(复跑原因=master 推进,合法复跑况②) | §5 闸读数 |
|
||||
| 用户裁 | 11 号回放确定性对拍 | **已获批准**:复跑带 `PARITY_APPROVED=1` 实跑三变体×20 局同种子逐字节比 | 本次复跑 |
|
||||
@@ -0,0 +1,273 @@
|
||||
# 验收审计:iter37 四卡(独立审计方,2026-10-25)
|
||||
|
||||
> **性质**:合回前独立验收审计(test-conventions 撤销证明与验收闭合计口径;卡① §8.3/卡②③④ §8 末段规定的合并前置件)。审计方未参与实现。
|
||||
> **被审对象**:worktree `D:/code/g-plan2-iter37`(分支 `iter37`),`git diff master...HEAD`=15 commits/75 文件。开工指令记为 14 commits/74 文件;审计期间并行会话追加 `356029d0`(只写 `reports/iter37-拆分卡缺口-2026-10-25.md`,零代码面)。
|
||||
> **输入**:四张需求卡片+`reports/iter37-实现报告-2026-10-25.md`(§2 对照表/§3 等价三证/附录 A/B/C)+代拍板单+反哺点清单+闸回执 `game/tests/.gates/receipt.json`(commit `9e3e2667`,domain=full,all_green=true,dirty_game=false)。
|
||||
> **方式**:全部结论自己取证——逐行 grep 盘面、`git show master:<file>` 逐函数对拍(含 python 机检对键序/取值表达式/掩码表穷尽比对)、单件直跑 5 个套件+一次自跑撤销证明。报告里写「绿」不采信。零全量闸重跑、零生产码改动。
|
||||
|
||||
---
|
||||
|
||||
## 一、总判定
|
||||
|
||||
**可以合并**——四卡验收面闭合:卡① 19 单元全部在盘且有断言,卡②③④ 等价迁移经本审计独立证实(含 RNG 调用序与断点 27 键逐表达式对拍),零测试削弱,卡④ P-B 撤销证明本审计实跑复现成功且还原复绿。
|
||||
|
||||
合回前三件事必须做(都不动生产码):
|
||||
|
||||
1. **回执与 HEAD 不同位**:回执钉 `9e3e2667`,HEAD 现为 `356029d0`(追加的 reports/ 文档件)。合回前按域重跑所选档一次,或由 guard 明确接受「回执 commit 落后一个纯文档提交」。
|
||||
2. **实现报告三处指认须更正/补申报**:见第六节 F-1/F-2/F-3(一处真实入口指认不实、一处机检线冒充卡片预期、一处未申报的查表算法重构需追加代拍板追认)。
|
||||
3. **呈报 11 号闸(回放确定性对拍)是否发起**:它是卡④「RNG 消费序不漂」的最强独立判据,回执记 NEED-APPROVAL 未跑;本审计用静态对拍替代(结论=同序),但档位发起权归用户。
|
||||
|
||||
---
|
||||
|
||||
## 二、检查一:改动—验收对照表逐行核对
|
||||
|
||||
### 2.1 卡① d1–d19(实现报告 §2 表 + 附录 A 尾缀索引)
|
||||
|
||||
判定列=盘面实据是否存在+入口是否真链。行号一律给 HEAD 实测值。
|
||||
|
||||
| 单元 | 盘面实据 | 判定 |
|
||||
|---|---|---|
|
||||
| d1 `is_same` | `game/core/damage_controller.gd:216` 判定符已改;断言 `game/tests/unit/battle_settlement/damage_controller_test.gd:243`/`:253`〔wd1〕,链路 `open_ticket→submit→units.unit_died.emit→flush→outcome()` 全真链 | 通过 |
|
||||
| d2 蓄力分档 | `game/presentation/views/standee_body.gd:33`(`_intent_charge` 成员)/`:178-179`(`_intent_charge = pid in CHARGE_SKILL_IDS`)/`:196`(`if _intent_charge:`);断言 `standee_fx_sweep_test.gd:95/97/99/101`+`theme_projection_test.gd:693` | 通过(入口深度见 4.3) |
|
||||
| d3 注释订正 | `game/presentation/views/ui_kit.gd:28` 失真引述已整段删除 | 通过(注释面,无断言属预期) |
|
||||
| d4 庆祝句柄 | `battle_end_overlay.gd:161-164`(close kill+remove_meta)/`:288-292`(先 kill 后建);断言 `standee_fx_sweep_test.gd:108/111/114`〔wd4〕绑 Tween 实例 `is_valid()` | 通过(报告记 `:281-287/156-161`,现址 `:285-295/158-164`=指针漂移) |
|
||||
| d5–d8 互斥四口 | `debug_overlay.gd:104`(`_dbg_btn.disabled` 并入 `_sync_sim_button`,且 `:84` 原直写已删);`tune_sim_controller.gd:14/32-33/36/70`(`_running`+`is_running()`+run 首尾置位);两守卫在 `main_debug_flow.gd:84`(d6 补 `is_running()`)与 `:72-79`(d7 补 `is_adventure`),main 留同签名委托 `main.gd:423-424/928-929`;断言 `standee_fx_sweep_test.gd:119/121`〔wd5〕`:130/131/132`〔wd8〕+`system_test.gd:290`〔wd6〕`:300`〔wd7〕 | 通过。system_test 从 `main._start_debug_levels()`/`main._on_tune_simulate(3)` 进入=信号实际接线的入口(`main_ui_build.gd:196-197`),非下层直调 |
|
||||
| d9 模态 fail-fast+合并 | `modal_stack.gd:22-25`(open 未登记 push_error+return)/`:28-38`(旧账∪新隐合并)/`:41-44`(close 未登记守卫);断言 `modal_flow_test.gd:126/129/132/134/136`〔wd9〕;V6-1~4 在役序列 `:40-48` 原样保留(diff 零触碰该段) | 通过 |
|
||||
| d10 信号契约 | `minesweeper_rules.gd:8-16` 两契约按 §2.1 三要素成文;全库扫描复现:`grep -rnP "^\s*signal\s+\w+\(.*\)\s*#(?!#)" game/` =**零命中** | 通过 |
|
||||
| d11 数值入表 | `data/schemas/shop_table.gd:15-16` 两 knob+`:132-135` 两域检(报告记 `:132-135`=精确);`data/tables/shop.tres:95-96` 值 15.0/0.8;消费点 `core/shop_session.gd:62`(spend_discount)/`:192`(relic_base_price),报告注「读点随 r3-2 落在 shop_session:62/:192」=精确 | 通过(ConfigDB 三访问器被 `2ed81668` 退役=卡片 d11 改法偏离,见 F-4) |
|
||||
| d12 target_id | 产发四处 `damage_controller.gd:169/371/401/505`;两口解析 `battle_stage_view.gd:308-310`(on_step_row_fx,id 先名兜底)/`:357-358`(enemy_standee_center 改签名);`row_pacer.gd:111/116/137/145`;`standee_body.gd:70` `enemy_id()`;断言三宿主共 11 行〔wd12〕 | 通过(报告/卡片记 :168/370/400/504/:342 全系 ±1~15 漂移) |
|
||||
| d13 孤儿注释 | `treasure_items.gd:51-56` 现仅 `inventory_count()` 与 `_usable_now` 头注,master :55-62 三段孤儿注释(持有数/同调位守卫谓词/持有件记录/丢弃)已删 | 通过 |
|
||||
| d14 公式单点 | `board_generator.gd:14` `static func target_mine_count`;两调用点 `:102`/`:339`;`:286 legality(b, params)` 去 db 参;调用点两处同批改(`:53` 内部+`board_gen_reward_test.gd:160`) | 通过(卡片记 test:145=master 行号,现 160) |
|
||||
| d15 常量化 | `action_economy.gd:14` `const CHARGE_LAYER_CAP := 3`;`:192/193` 两处改引;`:186` 注释随动 | 通过 |
|
||||
| d16a 英雄名入表 | `hero_table.gd:11` 字段+`:22-23` 非空域检;`hero.tres:10`;消费 `unit_container.gd:55` 直读 `String(db.hero.display_name)` | 通过 |
|
||||
| d16b int() 包裹 | `unit_container.gd`/`status_container.gd` 读侧包裹在位,由全量闸回归线承载(等价申报) | 通过(等价类,卡片即如此申报) |
|
||||
| d17 await 守卫 | `settlement_fx_view.gd:95-96` | 通过(无独立断言=卡片 §8.2 已申报豁免) |
|
||||
| d18 参数类型 | `tile_palette.gd:134 lumas_out: Variant = null`(报告记现址 :134=精确);本审计实跑 `python tools/audit_type_hints.py` → `[audit_type_hints] PASS——产品码类型闸归零(R1/R2/R3)` | 通过 |
|
||||
| d19 产出物 | `reports/` 三件在盘(实现报告/代拍板/反哺点) | 通过 |
|
||||
|
||||
### 2.2 卡② r1-1–r1-4+范围扩展
|
||||
|
||||
| 单元 | 盘面实据 | 判定 |
|
||||
|---|---|---|
|
||||
| r1-1 投影五函数 | `hud_presenter.gd:230/245/257/280/293` 五静态函数在盘;逐行对拍 master `main.gd` 原函数体=除接收者/参数化外**逐字一致**(本审计机检逐函数 diff:`status_curios` 仅成员→参、`career_data`/`save_select_data` 仅签名行变化、`status_data` 仅 `run_scope.runner`→`runner` 等 7 处参数化) | 断言入口不实:报告记「hud_presenter_test+ui_struct_probe 直调面」,`tests/unit/presentation/hud_presenter_test.gd` 全文零引用这五个新静态件(只测 outcome_text/board_variant_lines)。真实承载面=`probe/ui_click_probe.gd:789`(sv7 `_status_data()` 八键对拍)+`probe/ui_struct_probe.gd:60/94`(`_open_career`/`_open_save_select` 真开层链)+冒烟/系统测试。判 **通过(附更正)**,见 F-1 |
|
||||
| r1-2 解析回调四函数 | 新件 `presentation/board_resolvers.gd`(67 行)四函数齐(`debug_hero_override`/`identity_lookup`/`variant_mask_lookup`/`variant_mark_lookup`);对拍 master `main.gd:753-797`=除 `run_scope.settlement`→`_settlement_getter.call()` 外逐字一致;注入点 `main_ui_build.gd:200-205`(三参注入,与卡片 v1.2 接口块一致) | 通过 |
|
||||
| r1-3 文案三件 | `hud_presenter.gd:302/310/325`;逐字对拍同上(`phase_text` 仅四成员改参);main 消费点 `main.gd:493/470/476/858` | 通过 |
|
||||
| r1-4 探针直引零改动 | `main.gd:492`(`_gp_summary_text`→HudPresenter)、`:659`(`_status_data`→**MainOverlayFlow**)、`:726`(`_camp_data`→**MainOverlayFlow**);五处探针直引原行号原样在盘(ui_click_probe:74/101/112/789、ui_struct_probe:244),两探针文件本批零改动(不在 diff 内) | 通过(形态偏差:卡片接口块写「三件薄委托零参转发 HudPresenter」,实为两跳委托 main→main_overlay_flow→HudPresenter;语义等价,卡片代拍板白名单外但 commit b0d92524 与 §2 已记「三薄委托」,判为措辞不精确) |
|
||||
| 范围扩展四件 | `main_ui_build.gd` 238/`main_adventure_flow.gd` 213/`main_overlay_flow.gd` 155/`main_debug_flow.gd` 105 行;main 1506→946;冒烟 17/17 与 probe --click/--full 读数在 commit `b0d92524` 消息在案,回执 00/03/04 号闸 green | 通过(属代拍板 B-2,卡片 §5「不做」明写 `_build_ui` 留驻——超出卡片范围已由代拍板单申报待追认,本审计不判越权) |
|
||||
|
||||
### 2.3 卡③ r2-1–r2-3
|
||||
|
||||
| 单元 | 盘面实据 | 判定 |
|
||||
|---|---|---|
|
||||
| r2-1 瓦片族出根 | `views/tile_palette.gd`(261 行):装载缓存 7 成员(`:45-53`)+六 static(`flip_tex:123`/`normalize_floor_luma:134`/`srgb_lin:160`/`digit_ink_mode:170`/`contrast_y:198`/`ink_y:203`)+查表族(`is_wall:219`/`wall_tile_for:242`/`wall_center_tile:250`/`floor_tile_for:260`)+棋盘态注入 `bind_board:60`;`terrain_tile_sets_test.gd` 19 检查本审计实跑绿;`ui_contrast_probe.gd:140-150` 改引 `TilePalette.*` | 通过,**附未申报的算法重构**(见 5.5 与 F-3) |
|
||||
| r2-2 英雄族出根 | `views/hero_sprite.gd`(152 行,`extends Node2D` 符合卡片契约 4 硬约束)八函数齐(`update_hero:52`/`place_hero:75`/`frame_flash:99`/`notify_move:116`/`play_dig_bounce:122`/`feet:139`/`hand_point:146`/`sprite_scale:151`);board_view `:158-160` bind+`add_child`,`:397/403/409/414/426/431` 同签名委托;真实入口断言在 `probe/ui_input_probe.gd:293-352`(case⑦ 落位 ≤0.5px/case⑧ 材质链/case⑨ 纹理朝向/case⑩ 缩格重排与复位),该文件本批零改动 | 通过 |
|
||||
| r2-3 board_view 改引 | `board_view.gd` 937 行;13 条转发属性实测在 `:84-124`(7 条指 `_palette`、6 条指 `_hero_sprite`);`HERO_SPRITE_SCALE:44`/`HERO_GROUND_FRAC:45` 为指向件常量的**别名**(非重复字面值,无双源);旧址符号 `_normalize_floor_luma`/`_digit_ink_mode`/`_wall_center_tile`/`_hero_feet` 在 board_view 已不存在(本审计 grep 证实)→ 卡③ T2 规定的撤销形态成立 | 通过 |
|
||||
|
||||
### 2.4 卡④ r3-1–r3-3+契约 5
|
||||
|
||||
| 单元 | 盘面实据 | 判定 |
|
||||
|---|---|---|
|
||||
| r3-1 令牌池出根 | `core/curio_deck.gd` 259 行,卡片点名的 11 方法全在盘(`build:39`/`reset:31`/`token_identity:53`/`find_token:60`/`pool_stock:73`/`stock_snapshot:83`/`consume_deck_token:92`/`consume_pool_purchase:107`/`cap_ok:118`/`feat_ticket_consider:132`/`draw_candidates:150`)+四个内部helper;宿主委托实测 8 处:`adventure_runner.gd:356/443/455/460/465/634/639/644`(报告记 `:355/:443/:457/:465/:471/:641/:647/:654`,其中 :471 指向 `_finish_curio_pick`=非委托,:457/:641/:647 为空行,:654 在 `_redeem_feat_ticket` 体内);套件实跑 `adventure_feats_test`=138 checks 全绿,入口为 `start_adventure` 真链 | 通过(委托行号指针不实,见 F-2) |
|
||||
| r3-2 商店族出根 | `core/shop_session.gd` 339 行 21 函数同形;宿主委托 17 公开+2 私有=`level_runner.gd:780/784/788/792/796/801/807/812/816/820/824/828/832/836/840/844/848/852/856`(报告记 `_spend_discounted:801`、`_shop_draw_shelf:812`=精确);`set_shop_pool` 四参签名与缺省 `Callable()` 逐字对齐;实跑 `level_shop_economy_test`=186 checks 全绿;`meta_progression_forge_test.gd:733/736` 经宿主私有委托走件内折价(`=80`/`=1` 下限)在盘 | 通过 |
|
||||
| r3-3 断点单源 | `adventure_runner.gd:864 const BREAKPOINT_FIELDS`(27 键)+`_bp_parts():907`+`_bp_read():951`/`_bp_strategy():961`/`_bp_read_int():966`;`resume_adventure` 现 36 行(`:149-184`)+五小函数(`:188/204/230/252/264`);报告记 `:857`/`:909`=漂移 7/2 行。二次消费面 `:705-707` 与 `:762` 改走 `_bp_read`(node_id/visited_ids/aux_items)在盘。断言 `breakpoint_resume_test.gd:191/199/206`〔wr2〕三行在盘 | 通过(单源覆盖面见 5.2) |
|
||||
| 契约 5 接线行 | `adventure_runner.gd:745` `_runner.set_shop_pool(_curio_deck, _consume_pool_purchase, _feat_ticket_consider, _curio_cap_ok)`——报告记 `:745`=精确,四标识符全指委托/转发面,参数序不变 | 通过(入口标签不精确:报告写「pool_case_d_test 直调 set_shop_pool」,该处 `tests/unit/core/pool_case_d_test.gd:42-44` 自构 `LevelRunner` 直调=下层直调;接线行的真链覆盖在 `tests/unit/core/level_shop_economy_test.gd:1251 start_adventure(seed, {"shop_mode":"pool"})`。判 **通过(附更正)**) |
|
||||
|
||||
### 2.5 附录 A 断言尾缀索引核对
|
||||
|
||||
本审计用 `git diff master...HEAD -- game/tests game/probe` 抽出全部新增尾缀,与附录 A 逐行对:
|
||||
|
||||
- 新增带尾缀行计数=wd1×2/wd2×5/wd4×3/wd5×2/wd6×1/wd7×1/wd8×3/wd9×5/wd11×3/wd12×11/wd14×2/wd16×2/wr2×3,共 44 行;**附录 A 的 44 个 `文件:行` 指针全部命中,无一空指**(盘面 grep 复算见第二节各行)。
|
||||
- 删除行中的尾缀计数=**0**(`git diff ... | grep "^-" | grep 〔w*〕` 空输出)→ 无断言被删。
|
||||
- 「盘面新增带尾缀断言只有〔wr2〕三条」=属实(全库 grep 〔wr1〕/〔wr3〕/〔wr4〕 零命中)。推论:卡②③④ §8 表里挂在 wr1/wr3/wr4 行的「验收测试」从未以尾缀断言落码,由闸读数与件核承载——报告如实说明其语义,但卡片把闸读数写成尾缀断言属上游口径混用,记入第七节未覆盖面旁的观察。
|
||||
|
||||
---
|
||||
|
||||
## 三、检查二:撤销证明抽查(四条)
|
||||
|
||||
### 3.1 卡① d1(证据复核)
|
||||
|
||||
commit `1b9736f0` 消息明文记录「回退 d1 hunk → 同容异实例断言红(A 单据被 B 死亡误废),还原复绿」,与实现报告附录 B 首行读数(`[FAIL] …〔wd1〕`+`1/44 项失败`→`all green (44 checks)`)一致。可核性独立成立:判定符现值在 `damage_controller.gd:216`,回退即回到 `==`;夹具断言的判别力由 `damage_controller_test.gd:231` 前置检查(`a == b and not is_same(a, b)`)保证扫描面非空——非空转绿结构成立。
|
||||
|
||||
**判定:通过(取证级,本审计未重跑)。**
|
||||
|
||||
### 3.2 卡③ r2-3(证据复核+结构可核性)
|
||||
|
||||
commit `5c9c5f80` 消息逐字记录了与报告附录 B 相同的红行与复绿读数(19 检查复绿+error_scan exit 0)。本审计独立核其结构前提:`BoardView` 现盘面**不存在** `_normalize_floor_luma` 静态函数(grep 证实),故「测试改引回退旧址」必然产生 `Parse Error: Static function "_normalize_floor_luma()" not found in base "BoardView"` → 该红不由注入造成,属回退本批 hunk 的自然后果。
|
||||
|
||||
**判定:通过。** 性质提示:它证的是「旧址符号已消亡」,等价性判据本体在 render_gate(棋盘三图 changed=0.00%,且基线由卡① T3 `7389618f` 换代、早于卡②③——所以卡③ 的 0.00% 读数是相对自身改动量的有效对拍)。
|
||||
|
||||
### 3.3 卡② r1-3(证据复核+取证缺口属实)
|
||||
|
||||
结构前提本审计已核:`main.gd:493` 直呼 `HudPresenter.gp_summary_text(...)`,删承接体必致 Parse Error(报告记红行指向 main.gd:493=精确)。commit `b0d92524` 消息把撤销证明写作「→Parse Error 红→还原复绿」在案,而报告附录 B 该行自报「**缺该撤销的复绿日志**」。两处口径不一致,报告的下调比 commit 消息诚实。
|
||||
|
||||
缺口现由批级回执补上一半:回执 `00 冒烟`/`03 探针 --click`/`04 探针 --full` 在 HEAD 全绿,可作「还原后盘面复绿」的指认,但不是逐 hunk 复绿原始日志。
|
||||
|
||||
**判定:通过(附取证缺口申报,报告已自报)。**
|
||||
|
||||
### 3.4 卡④ P-B(本审计实跑复现)
|
||||
|
||||
动作:删 `game/core/adventure_runner.gd` 第 888 行 `"refresh_stock": {"strategy": "clamp"},` 一行 → 单件直跑 → `git checkout --` 还原 → 再跑。
|
||||
|
||||
变异后原始输出(红行原样,未加未减):
|
||||
|
||||
```
|
||||
[breakpoint_resume_test] FAIL — P8 键集与冻结清单逐位一致(27 键契约;增删键即红)〔wr2〕
|
||||
ERROR: [breakpoint_resume_test] FAIL — P8 键集与冻结清单逐位一致(27 键契约;增删键即红)〔wr2〕
|
||||
ERROR: [breakpoint_resume_test] 1/59 项失败
|
||||
```
|
||||
|
||||
还原后(同命令再跑):
|
||||
|
||||
```
|
||||
[breakpoint_resume_test] PASS — 断点往返/续玩确定性/幂等/退出清断点/装配存档回归/生成图换代/字段单源 全绿
|
||||
```
|
||||
|
||||
`git status --short` 输出为空(本审计自身零残留)。还原前变异态未提交,还原用 `git checkout --` 只回退该一个文件,未触碰其他改动。
|
||||
|
||||
读数与报告附录 B 记的红行/计数(1/59)**逐字一致**,且形态合规:回退本批 hunk、非注入式开关。
|
||||
|
||||
附带观察(不判缺陷,供写卡段参考):三条 wr2 断言里只有「键集==冻结 27 清单」承力。删一个登记项时,「登记键集==写侧实拼键集」不红——因为 `bp[key]` 由遍历 `BREAKPOINT_FIELDS` 生成,两侧同源,该断言结构上只能发现「登记了但 `_bp_parts` 没拼」的单向偏差;「策略标签落词表」同理对已登记键恒真。
|
||||
|
||||
**判定:通过(实跑复现)。**
|
||||
|
||||
---
|
||||
|
||||
## 四、检查三:测试削弱审查
|
||||
|
||||
### 4.1 删除行全清单(`git diff master...HEAD -- game/tests game/probe`,24 行删除逐条归位)
|
||||
|
||||
| 文件 | 删行 | 性质 | 判定 |
|
||||
|---|---|---|---|
|
||||
| `game/probe/ui_contrast_probe.gd` | 4 | `BoardView.*`→`TilePalette.*` 换址(常量×2+注释+静态调用),判据零变 | 非削弱 |
|
||||
| `tests/unit/core/adventure_feats_test.gd` | 1 | 注释级退役符号注记(`_token_identity`→`CurioDeck.token_identity`),commit `48248b21` 申报 | 非削弱 |
|
||||
| `tests/unit/core/board_gen_reward_test.gd` | 1 | `legality(b1, row, _db)`→`legality(b1, row)`,卡片 §8.3 申报在案 | 非削弱 |
|
||||
| `tests/unit/core/breakpoint_resume_test.gd` | 1 | `Kit.finish` 的 PASS 消息串追加「字段单源」四字 | 非削弱 |
|
||||
| `tests/unit/core/level_shop_economy_test.gd` | 2 | ①注释「15 固定锚」→「表 knob」;②`expect_p = int(ceil(15.0*…))`→`int(ceil(float(_db.shop.relic_base_price)*…))` | 判据口径改动,**非削弱**:同文件新增 `:1293-1295` 用硬编码 15.0 反算 `relic_price_pre` 并与件内 `pool_price("relic")` 逐位对拍〔wd11〕+`:262` 钉表值==15.0,硬锚未丢 |
|
||||
| `tests/unit/presentation/terrain_tile_sets_test.gd` | 11 | 全部是 `BoardViewScript.`→`TilePaletteScript.` 换址(含 `TILE_*`/`DIGIT_INK_CR_*` 常量直读与两次静态调用),断言表达式逐字不变 | 非削弱 |
|
||||
| `tests/unit/presentation/theme_projection_test.gd` | 4 | ①`:693` V4 断言判据换代;②`:810/:825` 两处注释同构引用改址 | 见 4.2 |
|
||||
| 三张 `golden/board_L*.png` | 二进制 | 基线换代:成因 `2f3a87e9`(与本批零因果)+用户裁「重制三张」+`tests/golden/README.md` 追加判定记录(6 行,卡① 契约 6 要求的显式呈报在案) | 非削弱(申报齐) |
|
||||
|
||||
阈值/扫描面类改动零处:`run_all.gd` 只加一行套件登记(`:62`);`error_scan`/`audit_type_hints`/`gdstyle_baseline.txt`/`tools/` 全目录零改动(`git diff --name-only master...HEAD -- tools/` 空输出)。
|
||||
|
||||
### 4.2 卡① §8.3 那句话的属实性
|
||||
|
||||
卡片原文:「零削弱;唯一既有测试改动=board_gen_reward_test:145/board_generator_test 的 `legality` 调用签名随 d14 同批改;既有断言零删除零放宽」。
|
||||
|
||||
- 「零削弱」「既有断言零删除」——**属实**(见 4.1 全清单+删除行尾缀计数 0)。
|
||||
- 「唯一既有测试改动」——**不成立**。卡① 自己触发的既有断言改动还有一处:`theme_projection_test.gd:693` V4 由「断言旧 GOLD_DEEP 判据在位」换成「断言分档布尔在位**且**旧判据消失」。该改动在 commit `2ed81668` 消息与实现报告 §2 d2 行(「V4 断言随卡① 换代补齐」)有申报,但不在卡片 §8.3 的申报句里。
|
||||
- 深层原因是卡片自相矛盾:d2 改法明写「颜色比较判据删除」,契约 5 又写「既有断言零删除零放宽」,而 V4 断言的正是那条待删判据的存在——两条约束在同一个输入上给不出同一个答案(agents.md「spec-AC 一致性」红线)。实现段的处理(判据换代、只增强不放宽、留痕)是这一矛盾下唯一不破红线的走法。
|
||||
|
||||
**未申报的其余改动:无。** 除上表 8 个文件面外,`game/tests`/`game/probe` 无其他既有件被触碰。
|
||||
|
||||
### 4.3 `standee_fx_sweep_test.gd` 断言绑面审查
|
||||
|
||||
| 断言族 | 绑的面 | 判定 |
|
||||
|---|---|---|
|
||||
| wd12 站桩两口(`:81-91`) | 经真实解析口 `stage.on_step_row_fx(...)`/`stage.enemy_standee_center(...)` 驱动,判据=**被闪白的站桩是哪一枚**(`s2._flash_count==1 and s1._flash_count==0`)与中心点等值(`world_to_shell(s2.position+s2.box*0.5)`)。`_flash_count` 是 master 既有的探针出口计数(`standee_body.gd:260`,非本批植入的观测桩) | 绑提交面——兜底路径(名匹配)若胜出,闪白必落 s1,断言即红 |
|
||||
| wd2 蓄力四断言(`:95-101`) | 读 `set_pending` 写入的判定标志位 `_intent_charge` | 绑决策落点,**未绑运动学后果**(③蓄力缓推分支实际入 tween 未取证);配合 `theme_projection_test:693` 的源码文本扫描,d2 的行为面缺一条可观测断言。卡片 §8.2 wd2 规定的是「真实调用链+回退红」,实现按卡执行——记为上游判据设计面,非实现段削弱 |
|
||||
| wd4 句柄三断言(`:108-114`) | 绑真 Tween 实例生命周期(首建 `is_valid()`/重开后旧句柄 `not is_valid()`/close 后元数据清空),经真实 `open_victory`/`close` 开合链 | 绑提交面,判别力强 |
|
||||
| wd5/wd8 互斥断言(`:119-121`、`:130-132`) | wd5 读真控件属性 `_dbg_btn.disabled`;wd8 在注入 driver 的回调内取 `is_running()` 读数(`drv.seen == [true, true]`)+收尾面板态 | 绑提交面;driver 注入位是 master 既有面(`tune_sim_controller.gd:_init(..., driver = null)`),非本批造桩 |
|
||||
|
||||
---
|
||||
|
||||
## 五、检查四:卡④ 等价性专查(本批最大风险面)
|
||||
|
||||
### 5.1 两拆件族逐字对比(对 `git show master:` 原实现)
|
||||
|
||||
- **CurioDeck**:11 个迁出方法与 master `adventure_runner.gd` 同族实现**逐表达式一致**(接收者化:`_curio_deck`→`deck`、`_curio_taken`→`taken`、`_feat_ticket_*`→`ticket_*`)。`consume_pool_purchase` 的未知 kind 拒绝分支(`curio_deck.gd:110-112` push_error+false)与 master `:478-480` 逐字同;`feat_ticket_consider`(`:132-143`)与 master `:775-786` 同——限购先返→配额先返→`pity >= step or rg.randi_range(1,100) <= chance`(短路保留:保底命中时**不掷点**)→命中清零 pity 并 `appeared += 1`/否则 `pity += 1`,记账先后零变。
|
||||
- **`reset()` 不清凭证三计数**:属实且正确——master `_reset_curio_state`(`:250-265`)本身就不清 `_feat_ticket_pity/_sold/_appeared`,`_feat_ticket_appeared` 在 master 亦不入断点、不在任何处复位;改后由 `CurioDeck.ticket_appeared` 同样只由 `_init` 归零。宿主 `_reset_curio_state`(`adventure_runner.gd:282-292`)与 master 除首两行改 `_curio.reset()` 外逐字同。**代拍板 B-5 的申报成立。**
|
||||
- **RNG 调用次数与顺序**(非 Boss 渠道):`_candidate_pool`(过滤,零掷点)→ `rng.open_stream("reward_pick")` 取流点同位 → `_shuffle(pool)`=`pool.size()` 次 `randi_range(i, size-1)`(与 master 内联循环同式同次)→ 由已洗的 pool 生成 sub(tier_rank≥excellent)→ `_shuffle(sub)`=`sub.size()` 次 → `_draw_exposure` 收集循环零掷点 → `feat_ticket_consider` 至多一次 `randi_range`。Boss 渠道:取流后直接 `_draw_weighted`,每轮 1 次 `randi_range(1, total)`,剔牌重掷走同一次数(`continue` 回循环再掷),与 master 内联加权段逐次同。**逐位核对通过。**
|
||||
- **ShopSession**:21 函数同形,成员→`_refs/_hooks` 读取(`_gp/_set_gp` 落 `wallet`=宿主 `_ledger` 同一字典对象,`level_runner.gd:33-35` 的 `gp` 属性也读写 `_ledger["gp"]`,无双账本)。`buy_product` 的出账→加算区→购血 hook→计数→emit 次序与 master 逐行同;`_emit` 取的是** mutation 后的 `_gp()`**=master 的 `wallet_changed.emit("buy", gp, …)` 同值。`_draw_shelf` 的内联洗牌抽出为 `_shuffle`,次数同;`pool_ticket.call(stream)` 仍复用同一 `shop_draw` stream(零新 scope)。
|
||||
- **换代重绑面核实**:`_bind_shop()` 五处(`:165/:205/:646/:670/:688`)恰好覆盖宿主引用被**整体替换**的全部位点——`_ledger` 重赋值(`:151`、`:202`)、`_attunement` 重赋值(`:645`)、`_tree_rules` 重赋值(`:669`)、`run_ledger` 重赋值(`:687`);`level_row` 为原地 `assign`(`:329`)故不需重绑,件内 `_level_index()` 每次现读。`:162 gp = 0` 落在 `_bind_shop()` 之前,但窗口内无件读点(件读点在 `_enter_node` 之后),无失真。**核对通过。**
|
||||
- **一处需知情的既有怪癖(非本批引入)**:`set_shop_pool` 捕获的是数组**引用**,之后 `_curio_deck = restored`(续玩)与 `reset()` 都是整数组替换,会使 `ShopSession.pool_deck` 指向旧数组——master 的 `_pool_deck` 同样如此,改后逐位不变(本批未「顺手修」=正确)。
|
||||
|
||||
### 5.2 `BREAKPOINT_FIELDS` 27 键逐键核(机检+代码验,未照抄报告 §3.2)
|
||||
|
||||
机检结果(本审计 python 对拍,别名词表归一后):
|
||||
|
||||
- 写侧键**序**:master `_snapshot_breakpoint` 字面量 27 键 = HEAD `_bp_parts()` 27 键 = HEAD `BREAKPOINT_FIELDS` 27 键,**三者序列完全相同**(`mk==hk: True`/`reg==hk: True`,对称差集为空)。
|
||||
- 写侧**取值表达式**:27 键逐键字符串比对(把四个转发属性名归一后)**零不一致**——含 `bonus` 四子键、`shop_shelf`/`shop_visit_buys` 的 `_runner != null` 三元式、`rng_counter: rng.counter()`、`graph_gen_v2: 1`。
|
||||
- 读侧覆盖面:master 读 25 键(另 2 键 `shop_shelf`/`shop_visit_buys` 写侧专用、两侧都不读,改后同);HEAD=16 键仍由 `_resume_*` 段内手写 `bp.get(...)`+9 键改走 `_bp_read`/`_bp_read_int`(attunement_charges/bonus_deck/adventure_counters/attune_refresh_y/refresh_stock/vision_counter_used/node_id/visited_ids/aux_items),两集合并集=master 的 25 键,**无增无减**。
|
||||
|
||||
逐键语义判定(与报告 §3.2 对照表交叉):
|
||||
|
||||
| 键类 | 判定 |
|
||||
|---|---|
|
||||
| keep_on_null 三键(`attunement_charges`/`bonus_deck`/`adventure_counters`) | **等价成立,但靠调用点守卫而非派生段**。`_bp_read:955` 的类型判别写作 `not (v is Dictionary or v is Array)`——比改前各站单一守卫**宽**(Dictionary 值喂给 `is Array` 站、Array 值喂给 `is Dictionary` 站,改前都会被拒、改后 `_bp_read` 都原样返回)。三处调用点各自保留了原 `is Dictionary`/`is Array` 判定(`:181`、`:214`、`:257`),净行为逐位不变。若日后某调用点删掉自身守卫,宽判别就成漏洞——登记标签与派生段职责边界不清,属可修的实现级技术债(不阻塞合回) |
|
||||
| clamp 四处 | `vision_counter_used`(`:260`)与 `refresh_stock`(`:259`)经 `_bp_read_int` → `maxi(0, int(bp.get(k, 0)))`=master 逐字同 ✓。**`hero_hp` 与 `bonus` 四子键不经派生段**:`:189` 仍写 `int(bp.get("hero_hp", 0))`(master 同)、`:191-194` 仍写四行 `maxi(0, int(...))`(master 同)。改前改后同义 ✓,但 `hero_hp` 的 `clamp` 标签名不副实(其 clamp 实为 `_resume_params:239` 的 `mini` 上限钳制,非 `maxi(0,…)`),且两键未真正单源化。**报告 §3.2 的 ✓ 列在「语义一致」义上成立,在「由登记派生」义上仅 9/25 键成立**——「单源」是半单的,报告未披露这一层 |
|
||||
| params_fallback 一处(`attune_refresh_y`) | `_bp_read_int("attune_refresh_y", bp, 0, params)` → `maxi(0, int(bp.get(k, int(params.get(k, 0)))))` = master `:205` 那行**逐字同式** ✓ |
|
||||
| plain 类(余 18 键) | 语义逐键同义;报告把 `shop_shelf`/`shop_visit_buys` 的「读侧实义」写成「`shop_bp_*()` 取数」——那是写侧取数,两键两侧都无读点(轻微表述错置,不影响结论) |
|
||||
| `dual_merge`/`token_migration` | `bonus_taken` 双向清零回填+身份维键(`:206-210`)与 master 逐字同;`bonus_pending` 候选字符串→普通档令牌归一+relic 三段键(`:264-279`)逐字同 ✓ |
|
||||
| 未登记键 fail-fast | `_bp_read:952-953` 对未登记键 `push_error` 后**继续按 plain 读**,`_bp_strategy` 缺省回 `"plain"`——注释称「fail-fast 不静默按 plain 兜」,码实为「报错+软兜」。行为无差(wr2 键集断言保证不可达),但注释与码不符,且与红线「fail-fast=致命中止无软回退」的口径有张力 |
|
||||
| `resume_adventure` 拆分 | 段序核实:ledger→curio 态→参数→计数器→pending/result→`_resume_bp`+attunement_charges→`_start_current_level`。与 master 唯一差异=`bp_pending` 的**读取点**从计数器段之前挪到之后(`:167`),其间无对 `bp` 的写点,纯局部变量取值时点移动,零行为差 ✓ |
|
||||
|
||||
### 5.3 断点五时点零增减零迁移
|
||||
|
||||
`git grep -n _snapshot_breakpoint` 两侧逐一对所属函数:
|
||||
|
||||
| master | 所属函数 | HEAD | 所属函数 |
|
||||
|---|---|---|---|
|
||||
| :509 | `_finish_curio_pick` | :483 | `_finish_curio_pick` ✓ |
|
||||
| :637 | `_refresh_curio_common` | :611 | `_refresh_curio_common` ✓ |
|
||||
| :806 | `_redeem_feat_ticket` | :665 | `_redeem_feat_ticket` ✓ |
|
||||
| :934 | `_on_level_finished` | :806 | `_on_level_finished` ✓ |
|
||||
| :983 | `_forward_choices_presented` | :855 | `_forward_choices_presented` ✓ |
|
||||
|
||||
计数 5↔5,所属函数一一对应,且 `_finish_curio_pick`/`_refresh_curio_common` 两函数体与 master 逐字节相同(`diff` rc=0);全仓无第六处调用(`shop_session.gd:303` 只是注释提及)。**契约 3 后半成立。**
|
||||
|
||||
### 5.4 转发属性读写面与双写面
|
||||
|
||||
| 宿主 | 条数 | 只读转发 | 可写回件内 |
|
||||
|---|---|---|---|
|
||||
| `adventure_runner.gd:60-77` | 4 | 0 | **4**(`_curio_taken`、`_curio_deck`、`_feat_ticket_pity`、`_feat_ticket_sold` 全带 set) |
|
||||
| `level_runner.gd:50-66` | 8 | **7** | 1(`_shop_purchased`;其 set 用于 `:164/:204` 两处把冒险级 `purchased` 字典别名进来,功能必需) |
|
||||
| `board_view.gd:84-124` | 13 | 11 | 2(`_hero_tex_idle`、`_hero_last`——探针与 battle_stage_view 的既有写点保号,`board_view.gd:164-165` 装载时即写) |
|
||||
|
||||
双写面核查:报告 §4 第 3 条「测试仍从宿主转发面直改件内多重集」三处指认**逐处属实**——`adventure_feats_test.gd:390-393`(`a11._curio_deck.remove_at(di)`,经 getter 拿到活数组下标写回)、`feat_vouchers_test.gd:92/98/108`(`a._curio_deck = [...]`,走 setter)、`level_shop_economy_test.gd:1351-1353`(`a8._curio_deck.remove_at(...)`)。
|
||||
|
||||
但该条**披露不完整**:生产码同样经宿主面写件内状态——`adventure_runner.gd:207-208`(`_curio_taken[id] = …`)、`:210`、`:222`(`_curio_deck = restored` 整数组替换)、`:253-254`(`_feat_ticket_pity/_sold` 赋值)、`:652-657`(`_redeem_feat_ticket` 内 `+=`/`-=`);`level_runner.gd:164/204`。即「件封装是名义的」不止测试面,续玩与兑付主链也是。存储仍是单点(件内一份,无副本),所以**不构成双源**,但「谁写件内状态」的写者数在宿主侧,P0 待办条目应据实扩面。
|
||||
|
||||
一处须留证的疑点(本审计实跑消解):`board_view.gd:165` 对**只读**转发属性 `_hero_tex_walk`(`:108-110` 仅 get)赋值。若该写不落件内,英雄行走帧永不切换。实跑 `res://probe/ui_input_probe.tscn` → 十八断言全绿、零 `SCRIPT ERROR`/零 setter 报错,其中 case⑨ 断言「移动后 `sp.texture != bv._hero_tex_idle`」——判据成立说明写点确实落进了 `HeroSprite.tex_walk`,行为无异常。留此记录供后续批知悉:只读转发属性上存在宿主写点,属计数守恒装置的连带面(P0 条目扩面时一并裁)。
|
||||
|
||||
### 5.5 卡③ 查表族与墨族被重构(非改名级变化)
|
||||
|
||||
对 master `board_view.gd` 逐函数比对,四个函数不是搬运而是改写:
|
||||
|
||||
- `_wall_tile_for`:master 18 段 if-链 → `WALL_MASK_TILE[16]` 查表+`_neighbor_mask` 位掩码(`:226-246`)。
|
||||
- `_wall_center_tile`:master 四连 if+三段阈值 → `WALL_DIAG_DIRS/WALL_DIAG_TILES/WALL_CENTER_PICK` 表驱动(`:250-255`)。
|
||||
- `_digit_ink_mode`:master 内联均值+四对比度+标志位 if/elif/else → 抽出 `_mean_of`/`_family_contrasts`(Vector4 四元组)+布尔重导出(`:170-195`)。
|
||||
- `load_board_tiles`:镜像件翻转六行去掉 `as Texture2D` 冗余转换,`var t := {}` → `Dictionary[String, Texture2D]`。
|
||||
|
||||
等价性本审计穷尽验证:16 个掩码组合逐一对拍 master if-链输出,**零不一致**(位序 `nf<<3|ef<<2|sf<<1|wf` 与表下标吻合;0/1 两块都落 `wall_w`,与 master 收尾分支同);中心三变体 `WALL_CENTER_PICK` 分布=6/2/2,与 master `m<6`/`m<8`/else 的 60/20/20 同;`crs.x/y/z/w` 与 master 的 p90_bright/p90_dark/mean_bright/mean_dark 及返回字典键一一对应,`dark`/`plate` 三态重导出真值表与 if/elif/else 同。
|
||||
|
||||
**但卡片契约 1 写的是「禁顺手改算法、禁合并/删函数、装载器/查表/英雄族除接收者化与缓存成员随迁外逐字一致」,代拍板白名单只给到「命名与函数名前缀取舍」**——新增三张 const 表与两个 helper 属白名单外的结构裁断,实现报告与代拍板单均未申报(grep 全套 reports/ 无掩码表/查表重构字样)。等价性成立 ⇒ 不必回退代码,但**须补追认**。
|
||||
|
||||
---
|
||||
|
||||
## 六、未通过项与例外清单
|
||||
|
||||
| # | 事项 | 缺什么 | 归属 | 建议处置(非裁断,供用户决) |
|
||||
|---|---|---|---|---|
|
||||
| F-1 | 实现报告 §2 卡② r1-1 行「真实入口=hud_presenter_test」 | `hud_presenter_test.gd` 零引用五个新迁静态件;真实承载面是 `ui_click_probe.gd:789`/`ui_struct_probe.gd:60/94` | **实现段可修**(只改 reports/ 一句) | 把该格改为指认实际承载面;顺带记:`career_data`/`save_select_data`/`bonus_summary_text` 至今无单元级断言,只有探针开层链与冒烟,若要为「投影」建回归断言属下一批 |
|
||||
| F-2 | 卡④ r3-1 委托行号 8 处中 5 处不指委托(`:471` 指 `_finish_curio_pick`、`:457/:641/:647` 为空行、`:654` 在 `_redeem_feat_ticket` 体内);r3-3 记 `const` 在 `:857`(实 864)、`_bp_parts` 在 `:909`(实 907);卡① d4/d12/d15/d17 行号漂移 1~15 行 | 取证指针精度——实体全部在盘,签名与语义本审计已逐个核实 | **实现段可修**(指针订正,零代码面) | 附录 A 的 44 个指针零错,可只校 §2 生产面指针 |
|
||||
| F-3 | 卡③ r2-1 查表族/墨族四处**算法重构**未在报告/代拍板/反哺点任一处申报 | 违卡③ 契约 1「禁顺手改算法、禁合并/删函数」字面;等价性本审计穷尽证实(16 掩码+60/20/20+三态真值表零差) | **实现段可修**(补代拍板追认行+实现报告逐字迁移核对表补注) | 追加 B-8 记「为压 S13 函数阈值而表驱动化,判据零变」,请用户追认;不建议回退 |
|
||||
| F-4 | 卡① d11/d16a 改法「ConfigDB 新增三访问器」被 `2ed81668` 撤销,消费面改直读 `db.shop.*`/`db.hero.*` | 卡片钉值表与盘面不符(契约 1「钉值表逐字」被后续批内提交推翻);红线「数值只经 ConfigDB 单点读取」义上仍守(`db` 即 ConfigDB,无自建 `load()` 表路径);已在报告 §2 两行括注+commit 消息申报 | **实现段已修(申报在案)**,卡片文本属历史件不改 | 记入反哺点第 8 条随文档批核一次「行访问器直读」是否等同「ConfigDB 单点」 |
|
||||
| F-5 | 卡②③ 缺「逐字迁移核对表(逐函数:原行界→新落点)」交付物 | 两卡各自完成定义 2 证①明文要求;报告 §3.1 只给卡④ 两拆件族。本审计已用机检补上证据(§2.2/2.3 的逐函数 diff 结论) | **实现段可修**(补一节表,或按吸收即死并入本审计) | 不必重做,把本审计 §2.2/2.3/5.5 的比对结果作为交付物指回本文件即可 |
|
||||
| F-6 | 实现报告 §1 读数表「卡片预期」列混记机检线 | 卡② 成文预期是 ≈1370–1380、卡③ 是 ≈880,表中分别填「≤999(S13 文件线)」「≤1000」并判「达成」;按卡片口径 main 946 是**超出**预期 424 行(因代拍板 B-2 扩面)、board_view 937 是**超出** 57 行 | **实现段可修**(改列名或加一行如实注记) | 与卡④ 两行「未达成」的写法对齐,同一把尺 |
|
||||
| F-7 | 卡① §8.3「唯一既有测试改动」与 V4 换代冲突(卡片自身 d2 改法×契约 5 互斥) | 上游卡片 spec-AC 不一致;实现处理正确且已留痕 | **须退回上游**(写卡段反哺,不在本批修) | 反哺点第 7 条同源:卡片钉「删除某判据」时必须同时列「该判据的在役断言如何换代」 |
|
||||
| F-8 | 闸回执 commit(`9e3e2667`)落后 HEAD(`356029d0`)一个纯文档提交 | 域覆盖:追加件只在 `reports/`,代码域零变化;但 guard 按 diff 推域校验回执时可能对不上位 | **工程/流程面**(非四卡缺陷) | 合回前重跑一次所选域档,或确认 guard 接受文档件后追加 |
|
||||
|
||||
无一项属「断言缺失/阈值放宽/入口造假」级;F-1 与 F-2 是取证指针不实,F-3 是白名单外结构裁断未申报(等价已证),其余为口径与交付物完整度。
|
||||
|
||||
---
|
||||
|
||||
## 七、本审计未覆盖的面(如实列出)
|
||||
|
||||
1. **未重跑全量闸**——遵指令。09 静态扫描(S11/S13)、10 熵增闸、06/07/08/08c/08d 文档域各闸、05 渲染闸、00-04 冒烟/系统/单元/probe,均**只采信回执**+卡③/卡② commit 消息读数。例外:本审计自跑了 `tools/audit_type_hints.py`(PASS)与六件单跑——`breakpoint_resume`(59,含变异复现两次)/`level_shop_economy`(186)/`adventure_feats`(138)/`standee_fx_sweep`(18)/`terrain_tile_sets`(19)/`theme_projection`(162)+探针单件 `ui_input_probe`(十八断言)——全部与报告读数一致、零 `SCRIPT ERROR`。系统测试/冒烟/渲染闸/其余探针段未自跑。
|
||||
2. **11 号回放确定性对拍未跑**(回执 NEED-APPROVAL)。它恰是卡④「拆件后 RNG 消费序不漂」最强的独立判据;本审计的替代证据是静态逐调用点序比对(§5.1)+同种子既有断言,**未做改前改后回放逐位对拍**。发起与否归用户。
|
||||
3. **未跑 MC/未动 `sim-data/` 锚**——遵「无数值改动零跑」;因此卡④ 的数值面等价只到「现算公式与读表值同义」这一层。
|
||||
4. **撤销证明只实跑了卡④ P-B 一条**。卡① d1/d2/d4/d5/d8/d9/d10/d12、卡② r1-3、卡③ r2-3、卡④ P-A/P-C 共 11 条=取证复核(commit 消息+报告附录 B 原文+结构前提独立核实),未逐条重演。原始日志目录 `.iter37-logs/` 已由 `6b23bc46` 删除,取证只能靠转录读数。
|
||||
5. **人工目检未做**(真人试玩项登记在实现报告 §5 七条,按红线只登记不阻塞)。呈现层拆件的观感等价证据止于 golden 逐像素 0.00% 与 probe 断言,未看实拍图。
|
||||
6. **未审计非本批文件**:`battle_orchestrator.gd`(卡④ 契约 5 明写不碰,diff 亦无该文件)、`save_manager.gd`(卡④ 论定 save 侧零键登记,diff 亦无)——两者本批零改动,未复核卡片论断本身。
|
||||
7. **未核 `game/tests/验证集清单.md` 陈旧度**(反哺点第 5 条在册,不受闸覆盖);未核 gdstyle 基线陈旧键(反哺点第 6 条)。
|
||||
8. **`iter37-拆分卡缺口-2026-10-25.md`(`356029d0`)与 P0 待办条目的内容一致性未审**——属另一会话产出,不在四卡验收面内;只核了待办条目里「adventure_runner :60-77 四条/level_runner :50-64 八条」的行号指认(属实)。
|
||||
Reference in new issue
Block a user