fix(闸况): 全量档首跑四条新红处置三条+产出物三件落 reports/

- S11 禁用词:minesweeper_rules.gd:9/:10 契约注释两处「雷格」改规范名「危险格」(术语表退役词对照 :143 已裁替换,本批 d10 补契约时用词违表)
- V8 字符串 Callable:level_runner._bind_shop() 三处 Callable(self, "x") 改裸方法引用(Godot 4 方法名即值;迭代 27 T6 方法引用换装闸判据),source_guard_test 8/8 绿+level_shop_economy 186/curio_refresh_paid 21 绿
- 10 熵增闸图像越界:删除仓库根在途临时目录 .iter37-logs/(黄金图诊断 PNG 11 张与回退备份件,均未入库;撤销证明读数已转录实现报告附录 B)
- 产出物:实现报告(四卡实际对照表+卡④ 等价三证+27 键单源对照+七条披露+目检总清单+附录 A/B/C)、代拍板追认单、反哺点清单
- 08d 引用可核红项一处待裁:design/gdd/systems/跨局循环/生涯.md:55 指 adventure_runner.gd:1007-1018,本批 1050→989 行使引用超界,修复位在禁写面 design/
This commit is contained in:
DKChan committed 2026-10-25 18:09:30 +08:00
1 parent 84dc3e4bc0
commit 6b23bc46f1
5 files changed
+284 -5

No files matched your search

+3 -3
View File
@@ -762,9 +762,9 @@ func _bind_shop() -> void:
"tree_rules": _tree_rules,
"attunement": _attunement,
}, {
"wallet_emit": Callable(self, "_emit_wallet_event"),
"max_hp_gain": Callable(self, "_gain_max_hp_flat"),
"battle": Callable(self, "current_battle"),
"wallet_emit": _emit_wallet_event,
"max_hp_gain": _gain_max_hp_flat,
"battle": current_battle,
})
+2 -2
View File
@@ -6,8 +6,8 @@ class_name MinesweeperRules
extends RefCounted
## 揭示事实流:每格首次进入已开集恰发一次(已开格零事件)。
## 载荷键集(四处发射位并集):cell: Vector2i/kind: "safe"|"mine"/digit: int(安全格邻雷数;雷格 -1)/
## variant_ids: Array(地形变异身份,雷格空集)/channel: "initial"|"dig"|"chain"|"fx_reveal"/
## 载荷键集(四处发射位并集):cell: Vector2i/kind: "safe"|"mine"/digit: int(安全格邻雷数;危险格 -1)/
## variant_ids: Array(地形变异身份,危险格空集)/channel: "initial"|"dig"|"chain"|"fx_reveal"/
## resource: bool(格面资源兑付资格:initial=false,其余 true)/dug_under_seal: bool(首格带封印直挖标记——
## initial 通道不发此键)。
## 发送时点:initial=install_board 初始展开逐格;dig/chain=_do_dig 揭示闭包内(本格 AP 扣费在其后);
+30
View File
@@ -0,0 +1,30 @@
# iter37 代拍板追认单(2026-10-25)
迭代 37 实现批(分支 `iter37`,四卡:①行为缺陷定点修 ②main 判离 ③boardview 拆件 ④runner 拆件与断点 schema 单点)批内由会话替你拍的决定,等你**追认或推翻**。授权发生在卡片审问阶段的只列「备案」;卡片没写清、会话自己拍的列「待追认」;会话拍错了的列「认错」。
## 一、待追认(卡片未写清,会话自拍)
| # | 决定 | 依据与后果 | 落点 |
|---|---|---|---|
| B-1 | **计数守恒装置:三处宿主文件共 25 条转发属性/常量别名**(board_view 13 条 :82-122、adventure_runner 4 条 :60-77、level_runner 8 条 :50-64),件内状态以宿主同名属性露出,只为让 S13 基线消息里的「类变量数」逐字不变 | 用户令「只改代码不改基线」+卡片契约 1「公开面零变化」+旧基线键含计数 ⇒ 数学上只剩"持平/达标/停卡"三途,会话选了持平。**已判定为处置错误**:本应停卡呈报(实现段零裁断)。且 master `37625317` 基线键治本后(改小/持平不红),该装置的存在理由已消失 | 已立 P0 待办条目「AdventureRunner 职责真拆分」(待办清单.md:5,2026-10-25 登记) |
| B-2 | 卡② **范围扩展**:r1-1~r1-4 之外多做 `_build_ui` 八步拆分 → `main_ui_build`,冒险/浮层/调试三流程族 → `main_adventure_flow`/`main_overlay_flow`/`main_debug_flow` | 卡片只列四族,但 main.gd 不降到 999 行内就冒新红;属"只改代码"令的直接推论。逐字搬运,成员访问改 root 前缀 | commit `b0d92524` |
| B-3 | 卡④ **件接口形态**:`CurioDeck._init(db_ref, rng_ref)`/`bind_handlers`/`reset()`;`ShopSession.bind(refs, hooks)`/`open_pool()`/`leave()`、件内状态全部写成公有 var(`deck`/`taken`/`shelf`/`visit_buys`…) | 卡片接口块只给 `_init(db)` 与 `set_shop_pool` 四参沿用;实际形态由"零新造协议+逐字可核"反推。公有 var 是为让宿主转发属性与既有 Callable 注入面零成本对接——代价是件自身无封装 | commit `e5ee4d04` |
| B-4 | 卡④ **登记项只含策略标签,不含"写侧取值器"**:`BREAKPOINT_FIELDS` 值=`{"strategy": ...}`,写侧取值由 `_bp_parts()` 的键名字典承载(未登记键即 `parts[key]` 越界 fail-fast) | 卡片 §104 写的是「键→{写侧取值键路径+读侧回退策略标签}」;GDScript 里 27 个取值 callable 只能写 lambda(S6 禁捕获 self)或字符串反射,两者都比现状差。读侧两处(`resume_adventure` 与 `_start_current_level` 二次消费)已同源派生 | [game/core/adventure_runner.gd:857](file:///D:/code/g-plan2-iter37/game/core/adventure_runner.gd#L857) |
| 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` |
## 二、认错(会话处置错误,已补账)
| # | 事实 | 已做的补救 |
|---|---|---|
| E-1 | 卡④ 遇到「卡片冻结公开面」×「S13 基线键含计数」互斥时,**没停卡呈报,自造了第三条路**(转发属性糊数)。按五段流水线实现段零裁断,这属上游缺陷该退回编排/写卡段 | 已在待办清单登记 P0 条目(含撤除依据与四件待裁缺口);本批按用户令「先按现状收口」不返工 |
| E-2 | P0 条目把同类装置只写成 12 条(adventure_runner 4+level_runner 8),**漏了 board_view 的 13 条**(卡③ 同款),覆盖面偏窄 | 记入本单与反哺点第 4 条,待文档批或下轮会话补注条目正文 |
## 三、备案(用户当场裁决,非代拍板)
1. 「全部都改代码,不允许改基线」——批内基线零改动贯穿全批(`tools/gdstyle_baseline.txt` 未动;commit `2ed81668` 九条漂移全用代码压回)。
2. golden 棋盘三图判失效 → 用户裁「重制三张基线」(成因 `2f3a87e9` 与本批零因果),复闸 changed=0.00%。
3. 「行为验收只走撤销证明,禁注入造红」(P0 令)——本批撤销证明全部为"回退本批 hunk → 断言红 → 还原复绿",无变异开关、无改值造红。
4. 本批直写根 `待办清单.md` 登记 P0 条目——用户本轮明示授权,越批性质禁写面的豁免仅限这一条登记。
5. 「本批按现状收口,真拆分另立 P0 卡」——用户裁。
+49
View File
@@ -0,0 +1,49 @@
# iter37 反哺点清单(2026-10-25)
迭代 37 实现批发现、需要写进 `design/` 权威文档或规约的点。**本批不落笔**(批性质禁令),逐条写清「哪个文件哪一节 → 改成什么 → 依据」。用户在会话里裁决后归文档批(doc-design 技能)落文,落完本条即删。
## 1. architecture 模块归属表 —— 登记本批十一个新件
- **文件/节**:[design/engineering/architecture/architecture.md](file:///D:/code/g-plan2/design/engineering/architecture/architecture.md) 核心层/功能层模块归属表
- **改成什么**:新增行——`core/curio_deck.gd`(CurioDeck:令牌多重集/抽签/cap/专长凭证三计数与判定)、`core/shop_session.gd`(ShopSession:商店双模式货架/定价/购买/刷新)、`presentation/views/tile_palette.gd`、`presentation/views/hero_sprite.gd`、`presentation/views/board_world.gd`、`presentation/board_resolvers.gd`、`presentation/main_ui_build.gd`、`presentation/main_adventure_flow.gd`、`presentation/main_overlay_flow.gd`、`presentation/main_debug_flow.gd`;并在 HudPresenter 既有行补「数据投影+文案拼装静态族」。
- **依据**:本批 commits `b0d92524`/`5c9c5f80`/`e5ee4d04` 的 diff。与待办清单「架构与规范对齐批」条目④(模块归属对齐)**并批落文**,避免两次改同一张表。
## 2. 存档序列化文档 —— 断点键登记载体址变化
- **文件/节**:[design/gdd/systems/表现与支撑/存档序列化.md](file:///D:/code/g-plan2/design/gdd/systems/表现与支撑/存档序列化.md) 断点域(SCHEMA_VERSION+快照锚)节
- **改成什么**:加注一句「断点 27 顶层键的登记单源=`core/adventure_runner.gd` 内 `const BREAKPOINT_FIELDS`(键→回退策略标签),写侧由 `_bp_parts()` 拼装、读侧由 `_bp_read`/`_bp_read_int` 两处派生」。若该文档逐键列了清单,逐键表本身**不改**(键名/缺省值/回退策略零变化)。
- **依据**:卡④ r3-3 单源化;wr2 断言(`breakpoint_resume_test` P8)已把「登记键集==写侧实拼键集」钉进回归面。
## 3. 秘宝/商店相关 GDD —— 实现载体址注记(机制零变化)
- **文件/节**:[design/gdd/systems/跨局循环/秘宝.md](file:///D:/code/g-plan2/design/gdd/systems/跨局循环/秘宝.md)(若记令牌池结构)与商店/经济相关篇目的实现落点段
- **改成什么**:只把「池与判定」逻辑的载体从 `adventure_runner` 私有族改注为 `CurioDeck`、「货架/定价/购买/刷新」载体改注为 `ShopSession`;四口径契约、池消耗即上限、A 链定价等**规则文字一字不动**。
- **依据**:卡④ 契约 1 零行为变更;等价三证之逐字迁移核对表(实现报告 §3)。
## 4. 待办清单 P0 条目覆盖面补记
- **文件/节**:[待办清单.md](file:///D:/code/g-plan2/待办清单.md):5 「AdventureRunner 职责真拆分(优先级=P0)」条目的**实况**属性
- **改成什么**:把「12 条转发属性」补成「**25 条**同类装置」——board_view 13 条(:82-122,卡③ 产物)+adventure_runner 4 条+level_runner 8 条;并在缺口里加第⑤件「卡③ 拆件件(TilePalette/HeroSprite)与 board_view 的字段归属重划」。
- **依据**:本批盘点读数(登记时只数了卡④ 两文件,漏了卡③——见代拍板单 E-2)。
## 5. 验证集清单(断言索引)陈旧
- **文件/节**:[game/tests/验证集清单.md](file:///D:/code/g-plan2/game/tests/验证集清单.md)
- **改成什么**:由 `python tools/extract_checks.py` 重生成一次(本批新增带尾缀断言=〔wd1/2/4/5/6/7/8/9/11/12/14/16〕四十五行+〔wr2〕三行,均不在册;`wc` 族系迭代 36 旧族,本批零新增)。
- **依据**:该文件只由脚本手工重生成、不受任何闸覆盖(在册已知盲区),换代批后必陈旧。
## 6. gdstyle 基线陈旧键清理(禁自动刷)
- **文件/节**:`tools/gdstyle_baseline.txt`
- **改成什么**:下次**人工**发起 `--refresh` 时一并清掉已不命中盘面的条目——`adventure_runner` 的 `_draw_curio_candidates`(85 行/26 局部/11 分支)、`resume_adventure`(108 行/13 局部/11 分支)、`_start_current_level`(53 行);`level_runner` 迁出函数名对应条目;`board_view` 已压回阈值内函数对应条目。
- **依据**:本批基线零改动令;新键形态(文件|规则|函数名)下陈旧键无害但属噪声。骤降守卫在 refresh 路径已内建(`37625317`)。
## 7. 规约反哺:重构卡必须显式裁"计数守恒装置"
- **文件/节**:[design/engineering/code-conventions.md](file:///D:/code/g-plan2/design/engineering/code-conventions.md) §1(一文件一职责)或 [design/engineering/test-conventions.md](file:///D:/code/g-plan2/design/engineering/test-conventions.md) 撤销证明段+项目技能 `.qoder/skills/req-card/SKILL.md`
- **改成什么**:加一条判据——「重构类需求卡片必须写明:**禁止为迎合机检消息文本(含计数)而保留或新增无效成员/别名**;遇机检键与卡片契约互斥,实现段一律停卡呈报,不得自造第三条路」。
- **依据**:本批 E-1 实证——卡片契约 1「公开面零变化」×旧基线键含计数=数学上只剩"持平/达标/停卡",实现段自拍糊数即违实现段零裁断。规则修订须先在真实任务上评估(本条已评估:本批三处踩同一坑)。
## 8. 观感/交互类无(本批零行为变更)
本批四卡全部为缺陷定点修+等价重构,无 GDD 数值与玩法语义变化;数值表新增两 knob(`relic_base_price`/`spend_discount`,卡① d11)与 `display_name`(d16a)已随卡① 提交入库,其**表值即事实源**,GDD 若已列同值则无需改动——文档批按现行 GDD 核一次即可,未核前不落笔。
+200
View File
@@ -0,0 +1,200 @@
# iter37 实现报告(2026-10-25)
迭代 37=**代码实现批**(分支 `iter37`,工作区 `D:/code/g-plan2-iter37`),四卡:
| 卡 | 需求卡片 | 收口 commit | 状态 |
|---|---|---|---|
| ① 行为缺陷定点修(19 单元 d1–d19) | reports/需求卡片-game行为缺陷定点修批-2026-10-24.md | `1b9736f0`/`0529e169`/`7389618f` | 收口 |
| ② main 组合根判离(r1-1–r1-4+范围扩展) | reports/需求卡片-重构main判离批-2026-10-24.md | `b0d92524`+`c99c23fb`(.uid 边车) | 收口 |
| ③ boardview 拆件(r2-1–r2-3) | reports/需求卡片-重构boardview拆件批-2026-10-24.md | `5c9c5f80` | 收口 |
| ④ runner 拆件与断点 schema 单点(r3-1–r3-3) | reports/需求卡片-重构runner拆件与断点schema单点批-2026-10-24.md | `e5ee4d04`+件核 `48248b21` | 收口 |
批内另两笔:`2ed81668`(九条 S13 基线外漂移全部以代码压回,基线零改动)、`84dc3e4b`(P0 重构条目登记,用户授权)。合回前 master 已并入(`d2c19791`,带入 S13 基线键治本 `37625317`)。
## 1. 完成定义读数(卡片「读数项非停机闸」如实申报)
| 件 | master | 本批 HEAD | 卡片预期 | 达成 |
|---|---|---|---|---|
| `main.gd` | 1506 | **946** | ≤999(S13 文件线) | 达成 |
| `views/board_view.gd` | 1219 | **937** | ≤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 | — | 净增 |
| 新件 `core/shop_session.gd` | — | 339 | — | 净增 |
| 新件(卡②③)`tile_palette` 261/`hero_sprite` 152/`board_resolvers` 67/`main_ui_build` 238/`main_adventure_flow` 213/`main_overlay_flow` 155/`main_debug_flow` 105 | — | 合计 1191 | — | 净增 |
四宿主文件合计 4774→3729 行(−1045),逻辑迁入 9 个新件;**行数不是本批的验收判据,等价与单源才是**(下两节)。
## 2. 改动—验收对照表(实际形态)
列义:落点=HEAD 盘面实际位置;真实入口=从生产入口进(非下层直调);撤销证明=回退本批 hunk → 断言红 → 还原复绿,等价类单元如实申报「撤不红属预期」并以等价断言承载。
### 卡① 行为缺陷定点修(d1–d19)
| 单元 | 落点(实际) | 真实入口断言 | 撤销证明/等价申报 |
|---|---|---|---|
| d1 单据归属 `==`→`is_same` | core/damage_controller.gd 来源敌作废判定 | damage_controller_test 双敌两断言〔wd1〕 | 回退该 hunk → 同容异实例断言红(A 单据被 B 死亡误废),还原复绿 |
| d2 蓄力档分档 | presentation/views/standee_body.gd `_intent_charge` | standee_fx_sweep_test(新增 18 项)+theme_projection_test V4 | 回退分档 → 三档判据红;V4 断言随卡① 换代补齐 |
| d3 注释订正 | presentation/views/ui_kit.gd:28(注释面,非行为改动) | 走查 | 不适用(随 d2 复核) |
| d4 庆祝 tween 句柄 kill | battle_end_overlay.gd:281-287/156-161 | 断言②〔wd4〕standee_fx_sweep_test(`open_victory`/`close` 真实开合链) | 回退 kill 段 → 红(T2④) |
| d5–d8 互斥四口 | presentation/views/debug_overlay.gd `_sync_sim_button`+main 两守卫+`is_running()` | system_test〔wd6〕〔wd7〕 | 回退守卫 → system_test 对应行红 |
| d9 ModalStack fail-fast+遮挡账合并 | presentation/modal_stack.gd | modal_flow_test V6-5(5 项〔wd9〕) | 回退 fail-fast → V6-5 红;V6-1~4 原样同绿 |
| d10 两信号契约成文 | core/minesweeper_rules.gd 头注+全库 28 处 `#`→`##` | 契约在位扫描(信号注释载体机检) | 回退契约段 → `undocumented=2` 红,还原归零 |
| d11 数值入表(relic 基价/散折) | data/schemas/shop_table.gd:15-16 字段+:132-135 域检+data/tables/shop.tres:95-96;消费面直读 `db.shop.*`(ConfigDB 两 getter 后由 `2ed81668` 退役,读点现随 r3-2 落在 shop_session.gd:62/:192) | level_shop_economy_test 三表值断言+现价逐位等价〔wd11〕 | 等价申报:原值迁移,撤销读表 → 〔wd11〕红(−1 读数) |
| d12 target_id 产发+站桩按 id 解析 | damage_controller 四处产发/standee_body 两口 | damage_controller_test+pacing_queue_test〔wd12〕 | 回退产发 → target_id 断言红 |
| d14 目标雷数公式单点 | core/board_generator.gd `target_mine_count`+两调用点、legality 去 db 参 | board_generator_test/board_gen_reward_test〔wd14〕 | 等价申报(同式单点),撤销 → 公式断言红 |
| d15 常量化(蓄力层上限) | core/action_economy.gd:185/191-192 `CHARGE_LAYER_CAP`(两处字面量+注释随动) | 全量闸回归线〔wd15〕(finish_round_stop 真实结算链既有套件覆盖) | 等价申报(同 d14 性质) |
| d16a HeroTable.display_name 入表 | data/schemas/hero_table.gd:11+:22-23 非空域检+hero.tres:10;unit_container.gd:55 直读 `db.hero.display_name`(`hero_display_name()` 访问器已由 `2ed81668` 退役) | spawn 真实链断言〔wd16〕 | 撤销读表 → 断言红 |
| d16b 六处显式 int() 包裹 | unit_container/status_container 读侧 | 既有系统测试覆盖 | 等价申报 |
| d13 孤儿注释 | core/treasure_items.gd:55-62(注释面,非行为改动) | 走查 | 不适用(非行为改动) |
| d17 await 守卫 | presentation/views/settlement_fx_view.gd:94-95 | 走查+惯例一致性〔wd17〕(如实申报:无独立断言) | 申报豁免(T2 标注) |
| d18 参数类型注解 | `lumas_out: Variant = null` 现址 views/tile_palette.gd:134(卡① 时在 board_view:998,卡③ 随函数迁件) | S9 类型闸 `audit_type_hints.py` 该行零命中〔wd18〕 | 回退类型 → S9 R3 命中红 |
| d19 产出物 | 本批三份 reports/ 产出物(实现报告/代拍板/反哺点) | 件核对〔wd19〕 | 删一落点 → 件核红 |
### 卡② main 组合根判离(r1-1–r1-4+范围扩展)
| 单元 | 落点(实际) | 真实入口断言 | 撤销证明 |
|---|---|---|---|
| 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-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` 三薄委托 | 探针原签名直调 | 等价申报(委托层零语义) |
| 范围扩展:`_build_ui` 八步+三流程族 | main_ui_build/main_adventure_flow/main_overlay_flow/main_debug_flow | 冒烟 17/17+probe --click --full | 逐字搬运等价;诊断转储 source 扫描断言零改动 |
### 卡③ boardview 拆件(r2-1–r2-3)
| 单元 | 落点(实际) | 真实入口断言 | 撤销证明 |
|---|---|---|---|
| r2-1 瓦片族出根 | **新件** views/tile_palette.gd(261 行:排版+装载+墨族判据+查表) | terrain_tile_sets_test 19 检查+ui_contrast_probe | 测试改引回退旧址符号 → `SCRIPT ERROR: Static function "_normalize_floor_luma()" not found`+error_scan exit 1,还原后 19 检查复绿 |
| r2-2 英雄族出根 | **新件** views/hero_sprite.gd(152 行,Node2D) | ui_input_probe 英雄落位/朝向/缩格重排断言 | probe --click 十八断言全绿为等价证据;撤销装配 → 落位断言红 |
| r2-3 board_view 改引 | board_view.gd 937 行(13 条转发属性+2 件引用压回 45 变量/27 公有方法) | render_gate 棋盘三图+菜单 golden changed=0.00% | 逐像素等价(golden 换代后复闸 0.00%) |
### 卡④ runner 拆件与断点 schema 单点(r3-1–r3-3)
| 单元 | 落点(实际) | 真实入口断言 | 撤销证明 |
|---|---|---|---|
| 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-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 撤销证明覆盖面内 |
**卡④ 撤销证明共三条**(P-A/P-B/P-C,各覆盖一单元),满足并超出卡片 T3「至少两条」。三条全为「回退本批 hunk → 断言红 → 还原复绿」,无注入式变异开关(用户 P0 令口径)。
## 3. 等价三证(卡④ 完成定义 2)
### 3.1 逐字迁移核对表(两拆件族)
- **CurioDeck**:11 个方法体逐字对齐迁出前宿主实现,仅接收者化(`_curio_deck`→`deck`、`_curio_taken`→`taken`、`_feat_ticket_*`→`ticket_*`)与 `db.adventure`/`db.feat_*` 访问面不变。**RNG 消费序逐位核对**:`draw_candidates` 内 `rng.open_stream("reward_pick")` 取流点、`_draw_exposure` 两次 `_shuffle`(全库→优秀子池)顺序、`_collect_one` 续取、`feat_ticket_consider` 的 `randi_range(1,100)` 与 pity 记账先后,全部与迁出前同一顺序同一分支;`_draw_weighted`(Boss 渠道)的 `_pool_weight`/`_weighted_index` 掷点次数与剔牌重掷路径同序。
- **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.2 断点 27 键单源对照表(改前读侧实义 → 改后策略标签,逐键一致)
| 键 | 标签 | 改前读侧实义(原 `resume_adventure`/二次消费) | 一致 |
|---|---|---|---|
| level_index | plain | `int(bp.get("level_index", 1))` | ✓ |
| node_id | plain | 二次消费 `int(_resume_bp.get("node_id", -1))` | ✓(改走 `_bp_read`) |
| hero_hp | clamp | `int(bp.get(...,0))` 入 ledger,随后越界钳到生效上限 | ✓ |
| bonus | clamp | 四子键各 `maxi(0, int(...))` | ✓ |
| gp / shop_purchased / shop_shelf / shop_visit_buys | plain | `int(...)`/`as Dictionary` duplicate/`shop_bp_*()` 取数 | ✓ |
| attunement_charges | keep_on_null | `bp.get(k, null)` + `is Dictionary` 才覆盖 | ✓ |
| graph_gen_v2 | plain | 缺键≠1 显式拒绝(代差检查) | ✓ |
| master_seed / rng_counter | plain | 直取 + `rng.restore_adventure(种子, 计数器)` | ✓ |
| keystone / visited_ids / aux_items / relics | plain | 直取/`as Array`/`restore_treasure_items(...)`/for-append | ✓ |
| bonus_taken | dual_merge | 既有 kind 键按快照清零回填+快照身份维键全量还原 | ✓ |
| bonus_deck | keep_on_null | `is Array` 才还原+relic 令牌 `feat_id` 随迁 | ✓ |
| bonus_pending | token_migration | 候选字符串→普通档令牌防御归一(relic 三段身份键随迁) | ✓ |
| feat_ticket_pity / feat_ticket_sold | plain | `int(bp.get(...,0))`(旧档缺键缺省 0) | ✓ |
| adventure_counters | keep_on_null | `is Dictionary` 才覆盖 | ✓ |
| vision_counter_used / refresh_stock | clamp | `maxi(0, int(...))` | ✓ |
| attune_refresh_y | params_fallback | `maxi(0, int(bp.get(k, int(params.get(k, 0)))))` | ✓ |
| bonus_result / keystone_drops | plain | `as Dictionary` 分支/`duplicate(true)` | ✓ |
键序=写侧拼装序=`_bp_parts()` 键集=wr2 冻结清单,三者同源(`_snapshot_breakpoint` 按登记顺序取值,未登记键 `parts[key]` 越界 fail-fast)。
### 3.3 读数对拍与闸
见 §5。
## 4. 披露(本批不体面之处,逐条如实写)
1. **计数守恒装置 25 条**:board_view 13+adventure_runner 4+level_runner 8 条转发属性,唯一作用是让 S13 基线消息里的类变量数逐字不变。**master `37625317` 基线键治本后(改小/持平不红)其存在理由已消失**,本批按用户令「先按现状收口」未返工;已立 P0 待办条目(登记时只算 12 条,漏 board_view 13 条——反哺点第 4 条补记)。判定:**处置错误**,遇「卡片契约×机检键」互斥应停卡呈报而非自拍第三条路(详见代拍板单 B-1/E-1)。
2. **卡的行数预期未达**(adventure_runner 850±10→989、level_runner 780→857):预期按 v1.0 旧边界算,实际委托层与登记段回填 ≈220 行。卡片自注「读数项非停机闸」,不构成停机条件,但差距必须留痕。
3. **件封装是名义的**:测试仍从宿主转发面直改件内多重集(adventure_feats_test :390-393、feat_vouchers_test :92-93、level_shop_economy_test :1351-1353)。真拆分卡片的验收面必须包含这三处直引改法。
4. **件↔宿主方法 Callable 注入成环**(`bind_handlers`/`bind(refs,hooks)`):沿用批前既有形态(原 `set_shop_pool` 即如此),RefCounted 环不报 fatal,但件生命周期由宿主持有,属已知欠账。
5. **golden 基线换代**(用户裁「重制三张」):成因 `2f3a87e9` 与本批零因果,判失效依据与复闸读数在 commit `7389618f`。
6. **待办清单.md 由本批直写**:属越批性质禁写面,用户本轮明示授权且仅限这一条登记(commit `84dc3e4b`)。
7. **等价类单元撤销不红**(卡① d11/d14/d15/d16、卡②③④ 全部委托层):属预期,以等价断言+读数对拍承载,已逐行标注。
## 5. 实机目检总清单(真人检测只登记不阻塞)
本批四卡零玩法语义变化,但动了呈现装配与商店/三选一接线,需真人试玩确认的项(**不写进根体验验证清单——该件属本批禁写面,是否入册由用户裁**):
1. 棋盘观感逐像素:普通/优秀/稀有档瓦片、封印纹、数字墨族、英雄待机/行走/撞击/挖掘四态与朝向、缩格重排与缺位回退(卡③ 拆件后同链)。
2. 商店:进店货架绘制、刷新(免费额度/付费价)、购买扣款与文案、离店再进店(货架入断点)。
3. 三选一停点:关底通关三选一呈现、刷新钮、空池跳过、专长凭证替换、确认后回血与加算区读数。
4. 断点续玩:中途关退出→「继续上局」→停在原节点、GP/生命/道具库存/特性/凭证限购读数一致。
5. 卡① 指定目检两项(卡片 §8.2 末段明文要求写进本清单):蓄力敌(heavy 技能敌)意图三档观感;同名敌受击闪白与弹道落点是否落对个体。
6. 蓄力三档观感分档、战斗结束庆祝浮动不叠加、批量模拟与调试浮窗互斥(连点不并发)。
7. 模态层重复 open 不再吞旧账(多层叠加关闭顺序)。
## 6. 遗留读数义务
- 全量域闸(两域档)回执 `game/tests/.gates/receipt.json`:读数见 §7 与验收审计报告。
- 本批**未跑 MC**(零数值改动,除卡① d11/d16a 入表为等值迁移),按红线「无数值改动零跑」不补跑;parity/对拍档位未动。
- `game/tests/验证集清单.md` 断言索引未重生成(不受闸覆盖)→ 反哺点第 5 条。
- gdstyle 基线陈旧键待人工 refresh 清理 → 反哺点第 6 条。
## 附录 A:断言尾缀索引(只读取证代理自 `git diff master...HEAD -- game/tests game/probe` 抽出的**本批新增行**)
尾缀族核实:卡①=`〔wdN〕`;卡②③④ 共用 `〔wrN〕` 族,其中卡面对照表里的 wr1/wr3/wr4 是**行号标识**(非行为改动/等价行),盘面新增的带尾缀断言只有 `〔wr2〕` 三条;`wc` 族系迭代 36 旧族,本批零新增。
| 尾缀 | 文件:行 | 套件 | 测什么 |
|---|---|---|---|
| wd1 | unit/battle_settlement/damage_controller_test.gd:243/:253 | damage_controller_test | 双敌不误废单据/自身死亡作废对照 |
| wd2 | unit/presentation/standee_fx_sweep_test.gd:95/:97/:99/:101 | standee_fx_sweep | heavy 置蓄力档/非蓄力技零置位/增益系零置位/普攻路径复位 |
| wd2 | unit/presentation/theme_projection_test.gd:693 | theme_projection | 分档布尔判据(换代后) |
| wd4 | standee_fx_sweep_test.gd:108/:111/:114 | 同上 | 首开建句柄/重开旧句柄已 kill/close 必杀 |
| wd5 | 同上:119/:121 | 同上 | 模拟期调试钮灰/收尾恢复 |
| wd6 | tests/system_test.gd:290 | system_test | 模拟态调试守卫早退 |
| wd7 | tests/system_test.gd:300 | system_test | 关间态模拟守卫早退 |
| wd8 | standee_fx_sweep_test.gd:130/:131/:132 | 同上 | 运行中 is_running/收尾 is_running/报告注入链路 |
| wd9 | unit/presentation/modal_flow_test.gd:126/:129/:132/:134/:136 | modal_flow | open/close 未登记 fail-fast+重复 open 遮挡账三半 |
| wd11 | unit/core/level_shop_economy_test.gd:262/:263/:1295 | level_shop_economy | relic 基价表值/散折表值/现价逐位等价 |
| wd12 | damage_controller_test.gd:271/:276 | damage_controller_test | fx 载荷携 target_id/伤害行携 target_id |
| wd12 | standee_fx_sweep_test.gd:75/:76/:78/:83/:88/:91 | standee_fx_sweep | enemy_id 访问器/同名敌按 id 命中/空 id 恒不命中/闪白落点/弹道落点/无 id 名兜底 |
| wd12 | unit/presentation/pacing_queue_test.gd:136/:139/:140 | pacing_queue | 标出传 id/弹道传 id/两路各接一拍 |
| wd14 | unit/core/board_generator_test.gd:75/:81 | board_generator | 公式单点同值对拍/metrics 读数同源 |
| wd16 | level_shop_economy_test.gd:264/:268 | level_shop_economy | 英雄名表值/spawn 读表同值 |
| **wr2** | unit/core/breakpoint_resume_test.gd:191/:199/:206 | breakpoint_resume | 单源键集==写侧实拼键集/键集==27 键冻结清单/策略标签落六类词表 |
无落码断言的卡面单元(与卡① §8.2 分行申报一致):wd3/wd10/wd13/wd15/wd17/wd18/wd19(走查、grep 静态扫描、全量闸回归线、件核对四类)。
接线行无尾缀:tests/run_all.gd:62(standee_fx_sweep 套件登记)。注释级标记:system_test.gd:271/283/292(wd6/wd7 段头注)、adventure_feats_test.gd:218(退役符号注记,commit `48248b21`)。
## 附录 B:撤销证明原始读数(`[FAIL]`/`SCRIPT ERROR` 原行+还原复绿)
| 单元 | 撤销动作 | 原始红读数(原样) | 还原复绿 |
|---|---|---|---|
| d1 | 回退 `is_same` hunk | `[FAIL] 同内容异实例敌死亡不误废他人单据〔wd1〕`+`[damage_controller_test] 1/44 项失败` | `damage_controller_test] all green (44 checks)` |
| d2 | 回退布尔分档 | `SCRIPT ERROR: Parse Error: Identifier "_intent_charge" not declared in the current scope.`(standee_body:161/166/178/179/196)+`Failed to load script ...standee_fx_sweep_test.gd with error "Compilation failed"` | `[standee_fx_sweep] all green (18 checks)` |
| d4 | 回退 kill 段 | `[FAIL] 首开胜利画面创建庆祝句柄〔wd4〕`+`[FAIL] 重开胜利画面:旧句柄已 kill、新句柄在位(至多一个活跃)〔wd4〕`+`1/18 项失败` | 同上 |
| d5 | 回退 disabled 半 | `[FAIL] 模拟运行期调试入口钮同置灰〔wd5〕`+`1/18 项失败` | 同上 |
| d8 | 回退 `is_running()` | `SCRIPT ERROR: Invalid call. Nonexistent function 'is_running' in base 'RefCounted (tune_sim_controller.gd)'.`(两次)+`[FAIL] 控制器运行中 is_running()=true(驱动回调内读数)〔wd8〕` | 同上 |
| d9 | 回退合并段 | `[modal_flow] FAIL — V6 重复 open 不吞遮挡账(close 低层恢复 mb——合并非覆盖)〔wd9〕`+`1/24 项失败` | `[modal_flow] all green (24 checks)` |
| d12 | 回退站桩按 id 半 | `[FAIL] 伤害行按 target_id 命中正确站桩(闪白落点)〔wd12〕`+`[FAIL] 弹道落点按 target_id 取站桩中心〔wd12〕`+`2/18 项失败` | 同上 |
| d10 | 回退信号契约段 | 契约在位扫描 `undocumented=2` 红 | 还原归零 |
| 卡③ r2-3 | 测试改引回退旧址符号 | `SCRIPT ERROR: Parse Error: Static function "_normalize_floor_luma()" not found in base "BoardView".` | `[terrain_tile_sets_test] all green (19 checks)` |
| 卡② r1-3 | 删 `HudPresenter.gp_summary_text` 承接体 | `SCRIPT ERROR: Parse Error: Static function "gp_summary_text()" not found in base "HudPresenter".`(main.gd:493)+冒烟 `[run_smoke] FAIL—— 退出码 = 1/冒烟失败 8 项 / 共 17 项` | **缺该撤销的复绿日志**——复绿以同批后续绿记录指认(冒烟 17/17、probe --click/--full 全绿在 commit `b0d92524` 读数段),如实申报为取证缺口 |
| 卡④ r3-2(P-A) | `pool_price` 委托体改 `return -1` | `[FAIL] relic 现价 = ceil(15.0×b^(关序−1))(读表与迁移前字面量逐位一致,-1)〔wd11〕` | `git checkout --` 后 `[level_shop_economy_test] all green (186 checks)` |
| 卡④ r3-3(P-B) | 登记里删 `"refresh_stock"` 一项 | `[breakpoint_resume_test] FAIL — P8 键集与冻结清单逐位一致(27 键契约;增删键即红)〔wr2〕`(1/59 失败) | 还原后 `PASS — …字段单源 全绿` |
| 卡④ r3-1(P-C) | `_find_token` 委托体改 `return {}` | 六条成片红:`[FAIL] 满配通关…`、`[FAIL] 通关几关 = 3`、`[FAIL] 钥石合计 = ΣBoss 首杀行值`、`[FAIL] 逐杀掉落明细恰 3 笔`、`[FAIL] 摘要携带主种子(42)`、`[FAIL] 通关三选一恰呈现 2 次、恰兑付 2 次` | 还原后 `[adventure_feats_test] all green (138 checks)` |
## 附录 C:合回前闸况变化与修法(本次全量档首跑 84dc3e4b,四条新红已全部处置并留痕)
| 闸 | 首跑读数 | 成因归属 | 处置 |
|---|---|---|---|
| 09 静态扫描 S11 | 禁用词命中 2 处=minesweeper_rules.gd:9/:10「雷格」 | **本批新增**(卡① d10 补信号契约注释时用词违术语表退役词对照 :143「雷格/惩罚格 → 危险格」) | 两处改「危险格」,`static_scan.sh` 单跑 `S11 ok(扫描面 237 个文件,词表 19 词)` |
| 02 单元与集成测试 | `[FAIL] V8 字符串 Callable 产品码零命中〔迭代27 T6〕`(source_guard_test 1/8) | **本批新增**(卡④ `_bind_shop()` 用三处 `Callable(self, "…")` 字符串形态,违迭代 27 T6 方法引用换装闸) | 三处改裸方法引用(Godot 4 方法名即值),source_guard_test 8/8 绿+level_shop_economy 186/curio_refresh_paid 21 绿 |
| 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 带入) | 记为改善,无需处置 |