diff --git a/reports/需求卡片-S9类型闸正则修复批-2026-10-24.md b/reports/需求卡片-S9类型闸正则修复批-2026-10-24.md index bcda067d..bc81e445 100644 --- a/reports/需求卡片-S9类型闸正则修复批-2026-10-24.md +++ b/reports/需求卡片-S9类型闸正则修复批-2026-10-24.md @@ -1,74 +1,75 @@ -# 需求卡片:S9 类型闸正则修复批(R2 恒零命中+static 函数漏网·存量归零) +# 需求卡片:S9 类型闸正则修复批(R2 恒零命中+static 漏网+跨行签名盲区·存量归零) -- 版本:**v1.0**(2026-10-24 成文;grilling 复核记录见 §12) -- 来源:[待办清单](../待办清单.md)「S9 类型闸正则失灵修复——R2 恒零命中+static 函数漏网」(2026-10-24 登记,来源=审计发现,设计面=工程直入,状态=待写卡)(唯一事实源:工程直入证据指认=审计报告 [reports/审计-game代码结构审查-2026-10-24.md](审计-game代码结构审查-2026-10-24.md) §二 C1〔已独立复现〕+本写卡会话逐处实查〔本卡 §3〕;规约依据=[test-conventions](../design/engineering/test-conventions.md) §6+[architecture](../design/engineering/architecture/architecture.md) 测试与质量域节) -- 归属:`tools/audit_type_hints.py`(正则修复)+ `game/core/`、`game/presentation/` 存量注解/豁免补齐(闸件批,**非迭代批**——gdstyle 条目同款执行形态) +- 版本:**v1.2**(2026-10-24 v1.0 成文→2026-10-25 grilling 第一轮修订 v1.1〔两阻断+三应修折入〕→第二轮复核**通过**(B-1 定界链经独立核实成立:iter36 禁令文+gdstyle 禁令后在库先例 01774323+登记口径三证据齐),一条建议级修正折入定稿;复核结论见 §12) +- 来源:[待办清单](../待办清单.md)「S9 类型闸正则失灵修复——R2 恒零命中+static 函数漏网」(2026-10-24 登记,来源=审计发现,设计面=工程直入,状态=待写卡+已写卡)(唯一事实源:工程直入证据指认=审计报告 [reports/审计-game代码结构审查-2026-10-24.md](审计-game代码结构审查-2026-10-24.md) §二 C1〔已独立复现〕+本写卡会话逐处实查〔本卡 §3〕;规约依据=[test-conventions](../design/engineering/test-conventions.md) §6〔闸件改动的变异验证义务——gdstyle 批在库先例 01774323〕+2026-10-24 用户 P0 令〔行为改动验收只走撤销证明——本批产品码面零行为差,见 §4 契约 3 定界〕) +- 归属:`tools/audit_type_hints.py`(正则修复)+ `game/core/`、`game/presentation/` 存量注解/豁免补齐(闸件批,**非迭代批**——gdstyle 批同款执行形态) - 排期:非迭代批不占迭代号,独立 worktree 批;估时 ≈0.75–1 工作日 - 开工门:U0(用户发令)+ grilling 复核门过(§12);与卡①先后皆可(§0) ## 0. 前置依赖与并行性 - **第〇步核对(2026-10-24 写卡会话)**:来源条目设计面=工程直入、状态=待写卡,条目现状带行号级证据(审计 §二 C1,正则两洞经 python 逐条对拍独立复现)→ **放行写卡**。 -- **与卡①(game 行为缺陷定点修批,同日写卡)**:零 hunk 交叠;卡① d18 已替本批消掉 `board_view.gd:998` 一件存量红——本批 T0 存量清点以**本批开工时盘面**为准(两卡先后皆可;若本批先行,卡①新增代码须全类型,其卡 §0 已注记)。 -- **与 gdstyle 引入条目(待写卡,非本批)**:gdstyle 格式类规则与本闸 S9 面重叠且应关格式类——两批互不依赖,gdstyle 落地时以其存量基线机制另行收编。 -- **改动域**:本批混触 `tools/`(文档域路径)与 `game/`(代码域路径)——批末闸档按 `tools/run_all_gates.sh` 自身域划分判定执行(卡内不另列清单);闸件自身改动的质量义务=变异验证(§7/§8)。 +- **与卡①(game 行为缺陷定点修批,同批写卡)**:零 hunk 交叠(grilling 实查确认:main.gd:565 vs :712/:1486、level_runner:632 vs :779/:895、unit_container:275 vs :55/:257/:270 皆同文件不同 hunk);卡① d18 已替本批消掉 `board_view.gd:998` 一件存量红——本批 T0 存量清点以**本批开工时盘面**为准(两卡先后皆可;若本批先行,卡①新增代码须全类型,其卡 §0 已注记)。 +- **与 gdstyle S13(2026-10-24 已落地,commit 01774323/8cdeb180)**:gdstyle 配置只开 quality/*、format/naming/order 全关——与 S9 类型面零重叠(其条目预告口径已兑现);本批产品码注解改动落在 S13 扫描面,禁产生基线外新违规。 +- **改动域**:本批混触 `tools/`(文档域路径)与 `game/`(代码域路径)——批末闸档按 `tools/run_all_gates.sh` 自身域划分判定执行(域划分唯一出处=脚本头注 :10-15;卡内不另列清单);闸件自身改动的质量义务=变异验证(§4 契约 3/§7 T2)。 ## 1. 目标与完成定义 -**目标**:修复 `audit_type_hints.py` 的 `FUNC_DECL` 正则两个洞,使 R2(有值返回缺返回类型)与 R3(参数缺类型)对「无返回类型带 `:` 尾的声明」与「`static ` 前缀函数」恢复命中能力;随后把因此浮出的全部存量红清零(补类型注解优先、`# type-hint: ignore` 带理由豁免兜底),闸退出码归 0;闸改动配变异验证(test-conventions §6)。 +**目标**:修复 `audit_type_hints.py` 的 `FUNC_DECL` 识别面三个洞,使 R2/R3 对「无返回类型带 `:` 尾的声明」「`static ` 前缀函数」「参数表折行的跨行签名」恢复命中能力;随后把浮出的全部存量红清零(补类型注解优先、`# type-hint: ignore` 带理由豁免兜底),闸退出码归 0;闸改动配变异验证(test-conventions §6)。 **改动单元清单**(钉值表,🔴 契约 1): | # | 位置 | 现状(实查) | 改法 | |---|---|---|---| -| g1 | `tools/audit_type_hints.py:25` `FUNC_DECL` | ①正则要求 `)` 后只跟 `->`/注释/行尾——无返回类型声明按 GDScript 语法必然以 `:` 结尾,**R2 目标形态 100% 失配**(R2 上线起恒零命中恒绿);②`^(\s*)func` 不认 `static ` 前缀——static 函数对 R2/R3 整体漏网 | 正则修复两洞:接受 `:` 尾形态(返回类型组与 `:` 尾并存)、声明头认 `static ` 前缀;规则语义(R1/R2/R3 判据与 `_init` 豁免、`# type-hint: ignore` 行级豁免)零变化 | -| g2 | 存量红清零(浮出即清) | 审计实证存量(闸当前退出码 0):`game/core/level_runner.gd:632`(`current_battle()` 无 `->`)、`game/core/attunement.gd:10`(`static func slots(db, save)`)、`game/presentation/main.gd:565`(`build_adventure_params` 两参)、`game/presentation/hud_presenter.gd:10-11`(refresh 续行参,**路径订正:实址非 views/**)、`game/core/reward_economy.gd:104/119/131/146`(query_identity/query_full_snapshot 等无 `->`)、`game/core/unit_container.gd:275`(`default_target()`);另 `tune_sim_controller.gd:24`(`_autoplay()` 无 `->`)等未列净 | T0 修复后全量清点红清单(实证九址为已知下限,非全集)→ 逐处补返回类型/参数类型注解;确不适型处 `# type-hint: ignore`+行内理由;清零后 `python tools/audit_type_hints.py` 退出码 0 | +| g1 | `tools/audit_type_hints.py:25` `FUNC_DECL` | 三洞:①正则要求 `)` 后只跟 `->`/注释/行尾——无返回类型声明按 GDScript 语法必然以 `:` 结尾,**R2 目标形态 100% 失配**(R2 上线起恒零命中恒绿);②`^(\s*)func` 不认 `static ` 前缀——static 函数 R2/R3 双漏;③**逐行匹配不认参数表折行**(`\((.*)\)` 不能跨行)——首行无闭括号的跨行签名永不进入扫描面(grilling 静态证明:实证址 hud_presenter 不修此洞则永不浮出) | 三洞修复:接受 `:` 尾形态(返回类型组与 `:` 尾并存);声明头认 `static ` 前缀;**续行拼接预处理**(声明行括号不平衡时并入续行直至平衡再匹配——写卡会话发现的第三洞,超出审计 C1 两洞原文,§11 呈报)。规则语义(R1/R2/R3 判据、`_init` 豁免、`# type-hint: ignore` 行级豁免)零变化 | +| g2 | 存量红清零(浮出即清) | 审计实证存量(闸当前退出码 0 全绿):`game/core/level_runner.gd:632`(`current_battle()` 无 `->`)、`game/core/attunement.gd:10`(`static func slots(db, save)`)、`game/presentation/main.gd:565`(`build_adventure_params` 两参)、`game/presentation/hud_presenter.gd:12-13`(refresh 跨行签名内 untyped 参——**行号订正**:审计与 v1.0 写 :10-11 实为注释行)、`game/core/reward_economy.gd:104/119/131/146`(query_identity/query_full_snapshot 等无 `->`)、`game/core/unit_container.gd:275`(`default_target()`);本会话补证 `game/presentation/tune_sim_controller.gd:24`(`func _autoplay():` 无 `->` 返回值) | T0 修复后全量清点红清单(实证址为已知下限,非全集)→ 逐处补返回类型/参数类型注解;确不适型处 `# type-hint: ignore`+行内理由;清零后 `python tools/audit_type_hints.py` 退出码 0 | **完成定义**(全部满足才算本批完成): -1. g1 正则两洞修复落地,规则语义零变化(R1 命中面与改前一致——R1 用独立正则不受影响,T0 对拍读数); +1. g1 三洞修复落地,规则语义零变化(R1 用独立正则 R1A/R1B 不受影响——T0 记改前 R1 读数、T2 对拍同值); 2. g2 存量红全量清点并归零:退出码 0、逐处红清单与处置(注解/豁免+理由)成表落实现报告; -3. 变异验证四步记录齐(§7 T2)——无变异红记录只准写「已实现,拦截能力未证」; -4. 批末按 `run_all_gates.sh` 域口径选档全绿(本批混触两域路径)+改前改后读数对拍;产出物写齐(T3)。 +3. 变异验证四步记录齐(§7 T2——闸件改动的拦截能力自证,gdstyle 批同款义务);无变异红记录只准写「已实现,拦截能力未证」; +4. 批末按 `run_all_gates.sh` 域口径选档全绿(S9 段 PASS 归零;S13 基线零新增)+改前改后读数对拍;产出物写齐(T3)。 ## 2. 设计事实源 | # | 出处 | 取用条款 | |---|---|---| -| D1 | 工程直入证据指认=审计报告 §二 C1(2026-10-24,正则行为经 python 逐条对拍独立复现;实证存量清单九址)+本写卡会话实查(§3) | 两洞机理与存量下限 | -| D2 | [test-conventions](../design/engineering/test-conventions.md) §6 | 新增/改写闸机判据必须变异验证自证拦截能力;操作四步+记录表 | -| D3 | [architecture](../design/engineering/architecture/architecture.md) 测试与质量域节 S9 行+static_scan 头注 | S9 载体=`tools/audit_type_hints.py`(R1/R2/R3 判据文字=现行规则语义,本批零变化);「规则扫描面为空=恒绿」静默失效模式的自警在案 | -| D4 | [code-conventions](../design/engineering/code-conventions.md) §4(语言纪律——类型闸为其机器闸) | 注解补齐的产品面纪律依据 | +| D1 | 工程直入证据指认=审计报告 §二 C1(正则行为经 python 逐条对拍独立复现;实证存量清单)+本写卡会话实查(§3) | 两洞机理与存量下限 | +| D2 | [test-conventions](../design/engineering/test-conventions.md) §6 | 闸机判据改写必须变异验证自证拦截能力;操作四步+记录表——**gdstyle 闸件批在库先例**(commit 01774323「变异验证:注入重复 load 红令→还原绿」同款义务与形态) | +| D3 | [architecture](../design/engineering/architecture/architecture.md) 测试与质量域节 S9 行+static_scan 头注 | S9 载体=`tools/audit_type_hints.py`(R1/R2/R3 判据文字=现行规则语义,本批零变化);「规则扫描面为空=恒绿」静默失效模式自警在案 | +| D4 | 2026-10-24 用户 P0 令(iter36-实现报告 §纪律变更段在案)+用户本批任务口径「闸改动配变异验证(test-conventions §6)」 | **定界**:行为改动验收只走撤销证明、禁注入造红;**闸件改动**的拦截能力自证走 §6 变异验证(用户任务口径+gdstyle 在库先例)——两条纪律的适用面互斥不冲突,规则文本修正归文档批(§11 呈报) | +| D5 | [code-conventions](../design/engineering/code-conventions.md) §4(语言纪律——类型闸为其机器闸) | 注解补齐的产品面纪律依据 | -## 3. 现状事实(2026-10-24 写卡会话主区实查;开工日 T0 复核) +## 3. 现状事实(2026-10-24 写卡会话实查+2026-10-25 grilling 独立补查;开工日 T0 复核) | # | 事实 | 出处 | |---|---|---| -| G1 | `FUNC_DECL = re.compile(r"^(\s*)func\s+(_?\w+)\s*\((.*)\)\s*(->\s*.+)?\s*(#.*)?$")`——无返回类型声明(`func f():` 形态)不匹配(`:` 不在允许尾集)→ R2 的 `RETURN_VALUE` 体扫描对该形态永不启动;`static func` 头不匹配 → static 函数 R2/R3 双漏 | `tools/audit_type_hints.py:25` | -| G2 | R2 判据链:`FUNC_DECL.match` → 无 ret 且非 `_init` → 收集更深缩进连续体 → `RETURN_VALUE`(`^\s*return\s+\S`)命中即红;R3:参数按 `PARAM_SPLIT` 拆分逐参查 `:`;`_init` 参数豁免;行内 `# type-hint: ignore` 整行跳过(:43-44);R1 用独立正则(R1A/R1B)与 FUNC_DECL 无关 | `tools/audit_type_hints.py:26-27/42-74` | -| G3 | 实证存量九址(审计列+本会话抽核五处确认形态:`level_runner.gd:632`、`attunement.gd:10`、`main.gd:565`、`reward_economy.gd:104/119`、`unit_container.gd:275` 均为无 `->` 返回值或 untyped 参数形态);另本会话补见 `tune_sim_controller.gd:24`(`func _autoplay():` 无 `->` 返回值)——存量全集待修复后实跑清点 | 上列 file:line;`game/presentation/tune_sim_controller.gd:24` | +| G1 | `FUNC_DECL = re.compile(r"^(\s*)func\s+(_?\w+)\s*\((.*)\)\s*(->\s*.+)?\s*(#.*)?$")`——①无返回类型声明(`func f():` 形态)不匹配(`:` 不在允许尾集)→ R2 体扫描对该形态永不启动;②`static func` 头不匹配 → static 函数 R2/R3 双漏;③逐行匹配,参数表折行(首行无闭括号)永不匹配——**grilling 静态证明**:实证址 hud_presenter.gd:12-13(static 前缀+折行双形态)不修第三洞则永不浮出 | `tools/audit_type_hints.py:25`;`game/presentation/hud_presenter.gd:12-13` | +| G2 | R2 判据链:`FUNC_DECL.match` → 无 ret 且非 `_init` → 收集更深缩进连续体 → `RETURN_VALUE` 命中即红;R3:参数按 `PARAM_SPLIT` 拆分逐参查 `:`;`_init` 参数豁免;行内 `# type-hint: ignore` 整行跳过(:43-44);R1 用独立正则(R1A/R1B)与 FUNC_DECL 无关——带 `->` 的普通函数声明现行确在命中面(`->\s*.+` 贪婪吞尾) | `tools/audit_type_hints.py:22-27/42-74` | +| G3 | 实证存量(审计列+本会话与 grilling 双重抽核形态一致):`level_runner.gd:632`/`attunement.gd:10`/`main.gd:565`(static 洞);`reward_economy.gd:104/119/131/146`/`unit_container.gd:275`(`:` 尾洞);`hud_presenter.gd:12-13`(static+折行——第三洞唯一实证址);`tune_sim_controller.gd:24`(`:` 尾洞,本会话补证)。grilling 独立判定:两洞修复后除 hud_presenter 外全部浮出,hud_presenter 须第三洞 | 上列 file:line | | G4 | 既有豁免先例:`board_generator.gd:281/331` 行内 `# type-hint: ignore(同 generate——测量面 stub 注入)`——豁免带理由的格式先例 | `game/core/board_generator.gd:281/331` | -| G5 | 闸机承载:static_scan.sh S9 段直跑 `python tools/audit_type_hints.py`(fail 聚合);闸头注(docstring)自述三条规则与白名单——g1 修复后头注描述无需变(规则语义未变,仅实现到位) | `game/tests/static_scan.sh:38-44`;`tools/audit_type_hints.py:3-14` | -| G6 | R1/R3 现行命中能力非空(R1 有存量拦截在役、R3 对非 static 函数在命中)——「零命中自检」因整体不空而未拦住 S9 的静默失效(审计定性与架构文档自警一致) | 审计 §二 C1;架构文档测试域节 | +| G5 | 闸机承载:static_scan.sh S9 段直跑 `python tools/audit_type_hints.py`(fail 聚合);闸头注自述三条规则与白名单——g1 修复后头注规则语义描述不变(实现到位非规则增删)。**S13 gdstyle 段已在役**(static_scan.sh 新增段,01774323)——本批产品码注解改动须 S13 基线零新增 | `game/tests/static_scan.sh` S9/S13 段;`tools/audit_type_hints.py:3-14` | +| G6 | 闸现状=退出码 0 全绿(R1/R2/R3 现行命中皆零——「R1/R3 仍有命中能力」指判据可达非在册命中,G2);audit_type_hints.py 内无逐规则零命中自检(static_scan 的 require_scan_face 只查扫描面文件数)——本批 g1 修复后,红清单浮出本身即扫描面非空的实证 | `python tools/audit_type_hints.py` 现状读数;`game/tests/static_scan.sh:27-36` | ## 4. 设计契约(红线,违反 = L3 停机呈报) -🔴 **契约 1 · 规则语义零变化**:g1 只修实现到位——R1/R2/R3 判据文字、`_init` 豁免、`# type-hint: ignore` 白名单、扫描面(game/core+game/data+game/presentation)、退出码协议全部不变;禁顺带收紧或放宽任何规则(新洞的发现走 L3 呈报,禁批内自裁扩面)。 +🔴 **契约 1 · 规则语义零变化**:g1 只修识别面到位——R1/R2/R3 判据文字、`_init` 豁免、`# type-hint: ignore` 白名单、扫描面(game/core+game/data+game/presentation)、退出码协议全部不变;第三洞(续行拼接)是实现面扩展非规则增删(§11 呈报);新洞再发现走 L3 呈报,禁批内自裁扩面。 -🔴 **契约 2 · 存量清零双通道纪律**:补类型注解优先(产品码可注解处一律注解——duck-typed 注入面如 `db_ref`/`panel_ref` 可注真实类型或以 `# type-hint: ignore(理由)` 豁免);每处豁免行内带理由(G4 格式);禁用「删参数/改签名」替代注解(那是行为改动,越本批权)。 +🔴 **契约 2 · 存量清零双通道纪律**:补类型注解优先(产品码可注解处一律注解——duck-typed 注入面如 `db_ref`/`panel_ref` 可注真实类型或以 `# type-hint: ignore(理由)` 豁免);每处豁免行内带理由(G4 格式);禁用「删参数/改签名」替代注解(那是行为改动,越本批权——本批产品码面**零行为差**,与 P0 令的定界依据)。 -🔴 **契约 3 · 变异验证义务**(test-conventions §6):g1 为改写闸机判据——四步变异记录齐(§7 T2),无变异红=「拦截能力未证」如实落报告,不得写「已验收」。 +🔴 **契约 3 · 变异验证义务(闸件改动)**:g1 为改写闸机判据——四步变异记录齐(§7 T2,gdstyle 批同款),无变异红=「拦截能力未证」如实落报告,不得写「已验收」;**变异实验只在闸件与本批注解面上做**(注入探针函数→闸红→还原),禁在生产行为面上做。 -🔴 **契约 4 · 实证九址全覆盖**:T1 清点后审计所列九址必须全部出现在红清单或已注解命中——**任一实证址未浮出**(如跨行签名第三洞)即 L3 停机呈报,禁静默放过。 +🔴 **契约 4 · 实证址全覆盖**:T1 清点后 G3 所列实证址(含 hud_presenter:12-13 与 tune_sim_controller:24)必须全部出现在红清单或已注解命中——任一实证址未浮出即 L3 停机呈报(第三洞拼接实现有缺陷的第一信号),禁静默放过。 ## 5. 范围边界 -**做**:g1 正则两洞+g2 存量清零+变异验证+产出物。 +**做**:g1 三洞+g2 存量清零+变异验证+产出物。 **不做**(明示去向): -- 跨行函数签名(参数表折行)的第三洞——若 T1 实证九址因跨行未浮出,呈报定夺,本批不自裁扩修; +- 第四类新洞(如 lambda 函数体、多行返回类型)——本批三洞为审计 C1 两洞+写卡会话静态证明必需的第三洞;再有发现走 L3 呈报; - S6/S7/S8 落地——条目③整条冻结待④(2026-10-24 用户裁); -- gdstyle 引入——另条目待写卡; +- gdstyle 引入——已另行落地(S13,8cdeb180),本批零触碰其配置与基线(仅产品码改动遵守基线零新增); - 顺带改任何产品码行为(注解与豁免注释除外——GDScript 类型注解零运行时行为差)。 ## 6. 关联文档同步面 @@ -77,9 +78,10 @@ | 文档 | 关联点 | 同步义务 | |---|---|---| -| [architecture](../design/engineering/architecture/architecture.md) 测试与质量域节 S9 行 | 「S9 在位」陈述不变(修复是实现到位非规则增删)——经 2026-10-24 写卡会话核对该节无「正则形态」级陈述 | 无关联文档(查讫) | -| `game/tests/README.md`(工具速查表若有 audit_type_hints 行) | T0 核:其描述为规则语义级则零改动 | 无关联文档(预期查讫,T0 复核) | -| `tools/audit_type_hints.py` 头注 | 规则语义未变,头注零改动(若头注含正则形态级描述则随 g1 订正——T0 核) | 实施本体(可写) | +| [architecture](../design/engineering/architecture/architecture.md) 测试与质量域节 S9 行 | 「S9 在位」陈述不变(修复是实现到位非规则增删)——写卡会话核对该节无「正则形态」级陈述 | 无关联文档(查讫) | +| [test-conventions](../design/engineering/test-conventions.md) §6(变异验证条款) | 与 2026-10-24 P0 令的定界(闸件改动保留变异验证/行为改动只走撤销证明)需一句适用面注记——规则文本修正归文档批(iter36 报告 §纪律变更段已预告) | 反哺点 · 列清单(①:定界句草案呈用户裁决后落文) | +| `game/tests/README.md` 工具速查表 audit_type_hints 行 | 描述为规则语义级则零改动(T0 核) | 无关联文档(预期查讫,T0 复核) | +| `tools/audit_type_hints.py` 头注 | 规则语义未变零改动;若头注含正则形态级描述则随 g1 订正(T0 核) | 实施本体(可写) | ## 7. 任务卡 @@ -89,45 +91,45 @@ | 文件 | 职责 | 行为改动 | |---|---|---| -| `tools/audit_type_hints.py` | g1 正则两洞修复(复用既有·修改) | 闸件改动 → wg1 | +| `tools/audit_type_hints.py` | g1 三洞修复(复用既有·修改) | 闸件改动 → wg1 | | `game/core/*.gd`、`game/presentation/*.gd` 存量位点 | g2 注解/豁免补齐(复用既有·修改;位点全集=T1 清点) | 非行为改动(注解面)→ wg2 | | `reports/实现报告-S9类型闸正则修复批-<完成日>.md` 等 | 产出物落位 | 非行为改动 → wg3 | ### 接口块 -- g1 修复后 `FUNC_DECL` 行为规格(断言引用以此为准):①`func f():`(无返回类型 `:` 尾)进入 R2/R3 扫描面;②`static func f(...)` 同普通函数进入 R2/R3 扫描面;③既有命中面不回退——改前命中的 R1/R3 样例改后仍命中(T2 变异③对拍)。 -- 最窄闸=`python tools/audit_type_hints.py`(直接退出码判读);全套闸=`tools/run_all_gates.sh` 按域划分选档。 +- g1 修复后 `FUNC_DECL` 行为规格(断言与变异引用以此为准):①`func f():`(无返回类型 `:` 尾)进入 R2/R3 扫描面;②`static func f(...)` 同普通函数进入;③参数表折行(首行 `(` 未闭合)经续行拼接后进入——hud_presenter:12-13 形态必浮出;④既有匹配面不回退(带 `->` 的普通函数声明改后仍匹配——T2③ 对拍)。 +- 最窄闸=`python tools/audit_type_hints.py`(直接退出码判读);全套闸=`tools/run_all_gates.sh` 按域划分选档(混触 `tools/`+`game/`)。 ### 落位与可复用性预检 -- **g1 改 `FUNC_DECL` 一处**——复用面:闸内单点常量,无第二处正则(G2);不新增文件不新增函数。唯一面:函数声明识别的唯一入口,修复即全局生效。分层:纯工具件零产品码依赖。 -- **g2 注解补齐**——零新增文件零新增函数;豁免格式复用 G4 先例;为什么不另立白名单文件:现行行级豁免通道(`# type-hint: ignore`)即 V7 成文白名单,增第二通道=双源。 +- **g1 改 `FUNC_DECL` 与预拼一段**——复用面:闸内单点常量与逐行循环,无第二处正则(G2);不新增文件不新增函数(续行拼接并入既有行循环)。唯一面:函数声明识别的唯一入口,修复即全局生效。分层:纯工具件零产品码依赖。 +- **g2 注解补齐**——零新增文件零新增函数;豁免格式复用 G4 先例;为什么不另立白名单文件:现行行级豁免通道即成文白名单,增第二通道=双源。 ### T0 事实坐实+改前读数(≈0.25d) -- [ ] 复核 §3 全部位点+头注/README 是否含正则形态级描述+跑改前读数(退出码 0、R1 命中数对拍基线)。可核查结果:改前读数表在案。 +- [ ] 复核 §3 全部位点+头注/README 是否含正则形态级描述+跑改前读数(退出码 0、R1/R3 命中数对拍基线——G6 预期皆零)。可核查结果:改前读数表在案。 ### T1 正则修复+存量清点归零(≈0.25–0.5d) -- [ ] 实装 g1 两洞修复。可核查结果:临时注入探针(任选产品码文件加 `func _probe_r2():\n\treturn 1` 与 `static func _probe_r3(a):\n\treturn a`)→ `python tools/audit_type_hints.py` 输出含两探针红(探针随后删除)。 -- [ ] 全量清点红清单(实证九址齐全性核对——契约 4)→ 逐处注解/豁免 → 退出码 0。可核查结果:红清单处置表(file:line+处置+豁免理由)落实现报告。 +- [ ] 实装 g1 三洞。可核查结果:临时注入探针(任选产品码文件加 `func _probe_r2():`+`return 1`、`static func _probe_r3(a):`+`return a`、跨行签名探针 `func _probe_ml(x,\n\ty):`+体)→ `python tools/audit_type_hints.py` 输出含三探针红(探针随后删除——探针即 §6 变异实验的注入件,闸件面实验合规)。 +- [ ] 全量清点红清单(G3 实证址齐全性核对——契约 4,hud_presenter:12-13 与 tune_sim_controller:24 必须浮出)→ 逐处注解/豁免 → 退出码 0。可核查结果:红清单处置表(file:line+处置+豁免理由)落实现报告。 ### T2 变异验证(≈0.25d) -- [ ] 四步变异记录(test-conventions §6;最窄闸直跑): - ①**R2 洞变异**:临时回退 g1 的 `:` 尾修复(单独回退该半)→ 注入的 `_probe_r2` 探针不再命中(红清单消失)→ 证明 R2 命中钉在 `:` 尾修复上; - ②**static 洞变异**:单独回退 `static ` 前缀半 → `_probe_r3` 探针不再命中 → 同理; - ③**回归线**:改前有命中的存量样例(R1 任一在册命中形态+非 static 函数 R3 命中形态)在修复后闸上仍命中(改前改后对拍,防修复吞旧命中); - ④**真实存量红**:T1 红清单中任取一址临时去掉新注解 → 该址复红 → 还原。 +- [ ] 四步变异记录(test-conventions §6;最窄闸直跑;实验面=闸件+本批注解,合规定界见 D4): + ①**`:` 尾洞变异**:临时回退 g1 的 `:` 尾修复半(只回退该半)→ `_probe_r2` 探针不再命中(红清单消失)→ 还原——证明 R2 命中钉在该修复半上; + ②**static 洞变异**:单独回退 `static ` 前缀半 → `_probe_r3` 探针不再命中 → 还原; + ③**既有面回归**:带 `->` 普通函数声明的匹配形态改前改后对拍同命中(防修复吞旧面)+R1 读数改前改后同值(R1 独立正则不受影响的实证)——**「改前」载体写死**=临时回退 g1 全量复现改前读数再还原(与 ①② 同为闸面回退实验,D4 定界内合规); + ④**真实存量红**:T1 红清单任取一址临时去掉新注解 → 该址复红 → 还原。 可核查结果:变异点(文件:行)、闸输出摘要、还原结论四行记录表进实现报告。 -- [ ] 验收步骤:全套闸按域划分选档跑一次,期望全绿(S9 段 PASS 归零读数)。 +- [ ] 验收步骤:全套闸按域划分选档跑一次,期望全绿(S9 段 PASS 归零读数+S13 基线零新增)。 ### T3 产出物落位卡(≈0.25d,末卡) - [ ] 写齐产出物:`reports/实现报告-S9类型闸正则修复批-<完成日>.md`(两单元状态+红清单处置表+变异记录表+改前改后读数对拍)+`reports/代拍板追认单-S9类型闸正则修复批-<完成日>.md`(§10 白名单内代拍项留痕)+`reports/反哺点-S9类型闸正则修复批-<完成日>.md`(§6 各条落点——查讫项写「无」)。可核查结果:三文件在 `reports/` 且逐条有落点。 -- [ ] 合回核对(非实现会话视角):变异记录表四步齐、九址覆盖核对齐、退出码 0 读数在案——缺任一项不合回。 +- [ ] 合并前置:**独立验收审计**(test-conventions §9.7——未参与实现的会话/子代理;只读本卡、实现报告、diff 与闸件,自跑最窄抽查不采信「已全绿」)完成且报告 `reports/S9类型闸正则修复批-验收审计-<完成日>.md` 逐行「通过」——审计面=变异记录表四步齐、实证址覆盖核对齐(含 hud_presenter/tune_sim 两补证址)、退出码 0 读数在案,缺任一项不通过;未通过不得合并。 -**估时合计 ≈0.75–1d**。切分预案:无超软盒预挂面(T1 若实证九址有跨行未浮出→L3 呈报即停,不吞工时)。 +**估时合计 ≈0.75–1d**。切分预案:无超软盒预挂面(实证址未浮出→L3 呈报即停,不吞工时)。 ## 8. 验证闸 @@ -135,34 +137,41 @@ | 需求点 | 改动 | 验收测试(名称+落点) | 层级 | 真实入口 | 变异/撤销证明 | |---|---|---|---|---|---| -| wg1 R2 洞 | `audit_type_hints.py:25` `:` 尾形态 | 探针 `_probe_r2` 命中〔wg1〕T1 步骤 1 | 闸机 | 闸真实跑批路径(static_scan S9 段同命令) | T2① 单独回退 → 探针漏网 | -| wg1 static 洞 | 同行 `static ` 前缀 | 探针 `_probe_r3` 命中〔wg1〕T1 步骤 1 | 闸机 | 同上 | T2② 单独回退 → 探针漏网 | -| wg1 回归线 | 既有命中面 | R1/R3 改前命中样例改后仍命中〔wg1-reg〕T2③ 对拍 | 闸机 | 同上 | 对拍差异即红 | +| wg1 `:` 尾洞 | `audit_type_hints.py:25` | 探针 `_probe_r2` 命中〔wg1〕T1 | 闸机 | 闸真实跑批路径(static_scan S9 段同命令) | T2① 单独回退 → 探针漏网 | +| wg1 static 洞 | 同行 `static ` 前缀 | 探针 `_probe_r3` 命中〔wg1〕T1 | 闸机 | 同上 | T2② 单独回退 → 探针漏网 | +| wg1 跨行洞 | 续行拼接预处 | 跨行探针 `_probe_ml` 命中+hud_presenter:12-13 浮出〔wg1-ml〕T1 | 闸机 | 同上 | 回退拼接段 → 跨行探针与 hud_presenter 址双双漏网 | +| wg1 回归线 | 既有匹配面 | `->` 形态对拍+R1 读数同值〔wg1-reg〕T2③ | 闸机 | 同上 | 对拍差异即红 | | wg2 存量归零 | `game/` 各存量位点注解/豁免 | `python tools/audit_type_hints.py` 退出码 0〔wg2〕 | 闸机 | 同上 | T2④ 去注解 → 复红 | -| wg3 产出物 | T3 三份 | 件核对〔wg3〕 | — | — | 缺项 → 件核红 | +| wg3 产出物 | T3 三份 | 件核对〔wg3〕 | — | — | 缺项红 | -**闸口径**:批末全套闸按 `run_all_gates.sh` 域划分选档(本批混触 `tools/`+`game/` 两域路径);S9 段归零 PASS 为本批主判据。**测试削弱申报**:零(闸判据只收紧到位、未放宽任何规则;产品码改动全部为注解/注释零行为差)。 +**闸口径**:批末全套闸按 `run_all_gates.sh` 域划分选档(混触 `tools/`+`game/`,域划分唯一出处=脚本头注);S9 段归零 PASS 为本批主判据。**测试削弱申报**:零(闸判据只收紧到位、未放宽任何规则;产品码改动全部为注解/注释零行为差)。 ## 9. 异常分级 -- **L1(自救)**:注解 vs 豁免的逐址取舍;探针文件的临时落位选择。 -- **L2(记录继续)**:存量清单超出审计九址的量级波动(正负皆记)。 -- **L3(停机呈报)**:实证九址任一未浮出(跨行签名第三洞嫌疑);修复导致改前命中面回退(T2③ 对拍红);正则修复需要触碰 R1 正则(超钉值表)。 +- **L1(自救)**:注解 vs 豁免的逐址取舍;探针注入的临时落位选择;续行拼接的实现细节(括号计数 vs 续行缩进判)。 +- **L2(记录继续)**:存量清单超出实证址的量级波动(正负皆记)。 +- **L3(停机呈报)**:任一实证址未浮出(拼接实现缺陷第一信号);修复导致既有匹配面回退(T2③ 对拍红);正则修复需触碰 R1 正则(超钉值表);第四类新洞出现。 ## 10. 代拍板白名单(超清单必呈报) 1. 逐址注解 or 豁免的取舍(豁免必须带行内理由)。 2. 探针注入的临时文件与清理时机。 -3. 提交切分与 worktree 分支命名。 +3. 续行拼接的实现写法。 +4. 提交切分与 worktree 分支命名。 ## 11. 待裁点 **零待裁点,开工门=U0。** -一处灰色地带推导定值(用户可否决,随 T3 反哺点呈报):**存量清零以注解优先、豁免兜底**——依据=code-conventions §4 类型纪律本意(产品码应类型化)+豁免通道 V7 成文为「显式白名单」非默认口;备选「全豁免快速归零」淘汰依据=闸修复后第一轮即全豁免=把 S9 再养回恒绿摆设。 +三处灰色地带已推导定值(用户可否决,随 T3 反哺点呈报): +- **第三洞(续行拼接)扩收**——超出审计 C1 两洞原文;依据=hud_presenter 实证址不修则永不浮出、契约 4 九址全覆盖必然停机(grilling 静态证明);备选「该址单行重排」淘汰依据=格式迁就闸而非闸达意;备选「移出实证址按未覆盖呈报」淘汰依据=明知的盲区留闸=再养恒绿面。 +- **闸件改动保留变异验证(与 P0 令的定界)**——依据=用户本批任务口径明文+gdstyle 闸件批在库先例(01774323 同形态实验);行为改动走撤销证明的 P0 令不受影响(本批产品码面零行为差);test-conventions §6 的适用面注记列反哺点归文档批。 +- **存量清零以注解优先、豁免兜底**——依据=code-conventions §4 类型纪律本意;备选「全豁免快速归零」淘汰依据=闸修复后第一轮即全豁免=把 S9 再养回恒绿摆设。 ## 12. 自审六查与 grilling 复核记录 -**自审六查(2026-10-24 写卡会话)**:①规格覆盖——g1/g2/wg1–wg3 逐条挂 T0–T3;②步骤扫描——一步一动作一可核查结果;③类型一致性——探针形态与 G1/G2 正则行为逐字对齐;④审查焦点+改动覆盖——补挂:回归线对拍(T2③,防修复吞旧命中)、九址全覆盖契约(契约 4,防跨行洞静默)、豁免滥用防线(§11 定值);⑤篇幅比例——两单元小卡不膨体;⑥落位与复用——零新增文件,豁免复用 G4 先例、白名单单通道。 +**自审六查(2026-10-24 写卡会话)**:①规格覆盖——g1/g2 挂 T0–T3、指到 wg1–wg3;②步骤扫描——一步一动作一可核查结果;③类型一致性——探针形态与 G1/G2 正则行为逐字对齐;④审查焦点+改动覆盖——补挂:回归线对拍(T2③)、实证址全覆盖契约(契约 4,含两补证址)、豁免滥用防线(§11);⑤篇幅比例——两单元小卡不膨体;⑥落位与复用——零新增文件,豁免复用 G4 先例、白名单单通道。 -**grilling 复核记录**:v1.0 成文后独立子代理对抗复核——记录见本节(复核后补写)。 +**grilling 第一轮复核记录(2026-10-25,独立子代理对抗复核)**:判回炉两阻断——B-1 验证面与 2026-10-24 P0 令冲突未呈裁;B-2 hud_presenter 跨行签名静态证明永不浮出、契约 4「九址全覆盖」=预排必然停机。随同三应修(B-3 G6「R1 存量命中在役」失实——闸现状全绿零命中;B-4 hud_presenter 行号 :10-11→:12-13;B-5 tune_sim_controller:24 升实证)+三建议(含域档引用脚本行号)。v1.1 折入:B-1 经在库证据定界(D4:用户任务口径+gdstyle 先例 01774323——闸件改动保留 §6 变异验证、行为改动走撤销证明,两纪律适用面互斥;定界句列反哺点呈裁);B-2 扩第三洞续行拼接(g1/契约 4/T1 探针/T2 对应全链落位,§11 呈报超出 C1 原文);G3/G6 事实按 grilling 订正;域档引用钉脚本头注 :10-15。复核结论:两阻断闭合、三应修落位(v1.1)。 + +**grilling 第二轮复核记录(2026-10-25,同代理续核)**:总判**通过**——B-1 定界链经独立核实成立(①iter36 纪律变更段原文全域禁令无闸件豁免=冲突真实;②commit 01774323 系禁令之后(2026-10-25 00:07)的 gdstyle 闸件批,明文执行闸面变异验证并全量域闸绿合回=开门先例;③gdstyle/S9 两条目登记原文同款口径——三证据齐,卡面按呈裁机制处理正确,B-1 撤回);B-2 第三洞全链落位(探针/契约 4/撤销证明联动)。余两条建议级:T2③ 改前载体写死(v1.2 已折入)、续行拼接后 R2 体收集含参数续行但无 return 故无害(实现期知晓项)。零阻断零应修,卡进可编排态。 diff --git a/reports/需求卡片-game行为缺陷定点修批-2026-10-24.md b/reports/需求卡片-game行为缺陷定点修批-2026-10-24.md index 4e45bf9a..9b8731d9 100644 --- a/reports/需求卡片-game行为缺陷定点修批-2026-10-24.md +++ b/reports/需求卡片-game行为缺陷定点修批-2026-10-24.md @@ -1,17 +1,18 @@ # 需求卡片:game 行为缺陷定点修批(代码结构审查 §二 行为缺陷+定点小件) -- 版本:**v1.0**(2026-10-24 成文;grilling 复核记录见 §12) -- 来源:[待办清单](../待办清单.md)「game 代码结构审查批——行为缺陷定点修+结构重构候选」(2026-10-24 登记,来源=审计发现,设计面=工程直入,状态=待写卡)(唯一事实源:工程直入证据指认=审计报告 [reports/审计-game代码结构审查-2026-10-24.md](审计-game代码结构审查-2026-10-24.md) §二+本写卡会话 2026-10-24 逐处 file:line 实查〔本卡 §3〕;规约依据=[code-conventions](../design/engineering/code-conventions.md) §2.1/§4+[test-conventions](../design/engineering/test-conventions.md) §6/§9) +- 版本:**v1.2**(2026-10-24 v1.0 成文→2026-10-25 grilling 第一轮修订 v1.1〔三阻断+九应修折入〕→第二轮复核**通过**,四条建议级修正折入定稿;复核结论见 §12) +- 来源:[待办清单](../待办清单.md)「game 代码结构审查批——行为缺陷定点修+结构重构候选」(2026-10-24 登记,来源=审计发现,设计面=工程直入,状态=待写卡+已写卡)(唯一事实源:工程直入证据指认=审计报告 [reports/审计-game代码结构审查-2026-10-24.md](审计-game代码结构审查-2026-10-24.md) §二+本写卡会话逐处 file:line 实查〔本卡 §3,含对审计三处读数的订正〕;规约依据=[code-conventions](../design/engineering/code-conventions.md) §2.1/§4+[test-conventions](../design/engineering/test-conventions.md) §9.4+2026-10-24 用户 P0 令〔行为改动验收只走撤销证明,禁注入造红实验〕) - 归属:`game/core/`(damage_controller / minesweeper_rules / level_runner / board_generator / action_economy / unit_container / status_container / treasure_items)+ `game/presentation/`(main.gd / debug_overlay / tune_sim_controller / modal_stack / views 下 standee_body / battle_end_overlay / battle_stage_view / settlement_fx_view / board_view / ui_kit)+ `game/data/`(shop 表与 hero 表扩列)+ 断言面(四件既有单测扩展+一件新单测+system_test 两断言+run_all 清单行) - 排期:未编入(卡片不预占迭代号;本卡估时 ≈3–3.5 工作日,低于编排硬下限 5 工作日,须与其他卡同批编入——归 iter-plan 段四查③) - 开工门:U0(用户发令)+ grilling 复核门过(§12)+前置:本卡先于 R1/R2/R3 重构批落地(§0) ## 0. 前置依赖与并行性 -- **第〇步核对(2026-10-24 写卡会话)**:来源条目设计面=工程直入、状态=待写卡,条目现状带行号级证据(审计报告 §二+本会话逐处实查复核,行号与报告一致,一处路径订正见 F10)→ **放行写卡**。 -- **条目拆分(2026-10-24 用户裁)**:条目原含「结构重构候选(报告 §三)」——五件已裁**全部另立**为 R1(main.gd 判离)/R2(board_view 拆件)/R3(runner 拆件+断点 schema 单点化)三卡,本卡缺陷修**先行落地**后重构再动(避免行号漂移与验收互相干扰)。缺陷九件中的**⑦明细行枚举漂移划归条目④**(「架构与规范对齐批」,词表归 13 还是 15 是④的裁点,本卡不自答、不碰 `battle_orchestrator.gd:15-19` 头注与架构文档 B1→D1 行)——本卡实收 = 八件缺陷+定点小件七件。 -- **与卡②(S9 类型闸正则修复批,同日写卡)**:两批零 hunk 交叠(卡②改正则+补注解,本卡改缺陷点),先后皆可;本卡 d18 给 `board_view.gd:998` 的 `lumas_out` 补类型=替卡②消掉一件存量红,卡② T0 存量清点以其落位时盘面为准(两卡 §0 互指)。本卡**新增代码全类型**(S9 R2/R3 面零新增债)。 -- **与迭代 36 已编两卡(文案与禁字清扫批/开场后缀营地灰字迷雾测点批,未开工)**:本卡不碰 `battle_log_view.gd`(d12 止步于行产发端与站桩解析端,见 F12)与 `level_map_screen.gd`;`main.gd` 触点(d6/d7)与两卡零 hunk 交叠。同批编入时按文件级 rebase 惯例处理。 +- **第〇步核对(2026-10-24 写卡会话)**:来源条目设计面=工程直入、状态=待写卡,条目现状带行号级证据(审计报告 §二+本会话逐处实查复核)→ **放行写卡**。 +- **条目拆分(2026-10-24 用户裁)**:条目原含「结构重构候选(报告 §三)」——五件已裁**全部另立**为 R1(main.gd 判离)/R2(board_view 拆件)/R3(runner 拆件+断点 schema 单点化)三卡,本卡缺陷修**先行落地**后重构再动。缺陷九件中的**⑦明细行枚举漂移划归条目④**(「架构与规范对齐批」,词表归 13 还是 15 是④的裁点,本卡不自答、不碰 `battle_orchestrator.gd:15-19` 头注与架构文档 B1→D1 行)——本卡实收 = 八件缺陷+定点小件七件。 +- **与卡②(S9 类型闸正则修复批,同批写卡)**:两批零 hunk 交叠(卡②改正则+补注解,本卡改缺陷点;grilling 实查确认:main.gd:565 vs :712/:1486、level_runner:632 vs :779/:895、unit_container:275 vs :55/:257/:270 皆同文件不同 hunk),先后皆可;本卡 d18 给 `board_view.gd:998` 的 `lumas_out` 补类型=替卡②消掉一件存量红,卡② T0 存量清点以其落位时盘面为准。本卡**新增代码全类型**(接口块签名已钉全类型——含返回类型)。 +- **与迭代 36(已于 2026-10-24 实现入库,commit 9468c70e 等)**:文案清扫批 u7–u9 触点 `board_view.gd:730/:778/:782` 在本卡两触点(:998 与信号载体行)带外、`battle_orchestrator.gd:797`(u13)与⑦头注 :15-19 不同 hunk、开场后缀批触点 :608-616 与本卡 :712/:1486 不同 hunk、状态面板瘦身卡触点 status_panel/main._status_data 与本卡零重叠——grilling 实查「同文件不同 hunk」成立;d10 信号载体 28 处含 `camp_overlay_view.gd`/`board_view.gd`(iter36 触过的文件),按**现行盘面**(iter36 已并入)T0 复核行号。 +- **与 gdstyle S13 闸(2026-10-24 已引入,8cdeb180)**:本批对产品码的改动落在 S13 扫描面(core/data/presentation 100 个 .gd)——改动禁产生基线外新违规(S13 差集判红)。 - **回放确定性对拍触面**:本批 diff 触 `game/data/tables/`(d11/d16 扩列)与 `game/core/damage_controller.gd`(d1)——11 号闸将判「触面、须用户批准发起」;本批无数值调整(表值=原字面量原样迁移)、MC 零跑,对拍是否发起归用户,闸以 NEED-APPROVAL 留痕不判红。 ## 1. 目标与完成定义 @@ -22,21 +23,21 @@ | # | 位置 | 现状(实查) | 改法 | 来源 | |---|---|---|---|---| -| d1 | `game/core/damage_controller.gd:215` | `if t.source_unit == u:`——Godot 4 Dictionary `==` 是逐键内容比较,内容全同双敌其一死亡会误作废对方单据 | 判定改 `is_same(t.source_unit, u)`(引用同一性);同内容不同敌的单据不再误作废 | 审计 §二 C6 | +| d1 | `game/core/damage_controller.gd:215` | `if t.source_unit == u:`——Godot 4 Dictionary `==` 是逐键内容比较。**生产不可达实证**(grilling 订正):`unit_container.gd:98` 每敌单位带自增 `handle_id`(:77/:114),任意两敌内容必异,真实 spawn 路径不会触发误作废;该行属**语义加固件**(引用同一性判定才是 `_on_unit_died` 的正确语义,且防御未来单位字典形态演化) | 判定改 `is_same(t.source_unit, u)`;定性=防御性语义加固(非行为修复——撤销不红属预期不适用,见 wd1 证明设计) | 审计 §二 C6(前提读数经本会话订正——审计所述「内容全同双敌」被 handle_id 排除) | | d2 | `game/presentation/views/standee_body.gd:171-172/188` | `set_pending` 蓄力档落 `GOLD_INK`(:172),`_play_intent_motion` 却判 `GOLD_DEEP`(:188)——③蓄力缓推分支恒不可达死代码 | 判据改布尔:新增成员 `_intent_charge := false`,`pid in CHARGE_SKILL_IDS` 分支内置 true,`_play_intent_motion` 判 `_intent_charge` 分档;颜色比较判据删除 | 审计 §二 C7 | -| d3 | `game/presentation/views/ui_kit.gd:28` | `GOLD_BRIGHT` 注释宣称「GOLD_DEEP 语义岗〔standee:199 意图判据…〕在役不动」——d2 落地后该宣称失真 | 注释订正:删 standee 意图判据引述(board_view:35/level_map:237 两处引用 T0 复核仍在则保留),意图蓄力墨改引 `GOLD_INK` | 审计 §二 C7 连带 | +| d3 | `game/presentation/views/ui_kit.gd:28` | `GOLD_BRIGHT` 注释宣称「GOLD_DEEP 语义岗〔standee:199 意图判据/board_view:35/level_map:237〕在役不动」——**三处引述全部失真**(grilling 实查:board_view:35 实为 `DEPTH_PX`、level_map:237 在 abandon 段、standee 意图判据即 d2 死代码,两文件 GOLD_DEEP/GOLD_BRIGHT 引用 grep 零命中) | 该括号引述整段删除(不留条件保留),意图蓄力墨改引 `GOLD_INK` | 审计 §二 C7 连带 | | d4 | `game/presentation/views/battle_end_overlay.gd:281-287/156-161` | `_play_celebrate` 建 `set_loops()` 无限 tween,`close()` 只隐藏不 kill——每次胜利叠加一个永不停的 tween | 新增成员 `_celebrate_tw: Tween`;`_play_celebrate` 开头 kill 旧句柄再建新;`close()` kill+置空(全库先 kill 后建惯例=board_view:362-364 先例) | 审计 §二 C8 | | d5 | `game/presentation/views/debug_overlay.gd:84` | `_dbg_btn.disabled = _ctx_locked`——调试钮不看 `_sim_running`(模拟钮 :101 看两态) | 调试钮 disabled 并入 `_sim_running`(`set_sim_running` 同步刷调试钮) | 审计 §二 C9 | | d6 | `game/presentation/main.gd:712-717` | `_start_debug_levels` 守卫只查 `is_adventure or settlement != null`,漏批量模拟运行态;:717 `reset_sliders()` 会作废在跑测量的滑条读数 | 守卫补 `_tune_sim.is_running()` 即返(模拟运行期调试钮已由 d5 置灰,此处为信号绕过 disabled 时的第二道闸) | 审计 §二 C9 | | d7 | `game/presentation/main.gd:1486-1491` | `_on_tune_simulate` 守卫只查 `settlement != null`,漏 `is_adventure` | 守卫补 `or run_scope.is_adventure` | 审计 §二 C9 | | d8 | `game/presentation/tune_sim_controller.gd` | 无运行态查询面——`run()` :37 起 `set_sim_running(true)`、:62 收 `false`,main 侧无从互查 | 新增 `var _running := false`+`func is_running() -> bool`;`run()` 首行置 true、收尾置 false(run 无早退分支) | 审计 §二 C9 | -| d9 | `game/presentation/modal_stack.gd:21-38` | `open()` 对未登记层(`_list.find(m)`=-1)静默隐藏全部已开层;同层重复 open 覆盖 `_occluded[m]` 致原被隐藏层永久卡隐 | fail-fast:`open()` 首行 find<0 即 `push_error` 且 return;同层已 visible 幂等直返;`close()` 对未登记层 `push_error` | 审计 §二 C10 | -| d10 | `game/core/minesweeper_rules.gd:8-9`+全库 28 处 | 两条核心信号零契约成文(违 code-conventions §2.1);全库信号注释载体 28 处 `#` 非 `##`(不进编辑器 F1 帮助) | :8/:9 按 §2.1 三要素(参数语义〔载荷键集按发射位并集:cell_revealed 四处 :129/:303/:310/:345、seal_judged :476〕/发送时点/消费方依赖)补 `##` 契约;全库信号声明行的 `#` 注释逐处换 `##`(注释内容逐字保留) | 审计 §二 定点清单① | -| d11 | `game/core/level_runner.gd:779/895`+`game/data/schemas/shop_table.gd`+`game/data/tables/shop.tres`+`game/core/config_db.gd` | relic 基价 `15.0`(:895)与散折 `0.8`(:779)是玩法数值字面量(自注 provisional/「shop.tres 词表扩列归数值批」)——违数值单一事实源 | ShopTable 新增两个 knob:`relic_base_price: float = 15.0`(域 [1.0,99.0])+`spend_discount: float = 0.8`(域 (0.0,1.0]),`validate()` 补两域检;ConfigDB 新增 `shop_relic_base_price() -> float`/`shop_spend_discount() -> float`(:337-341 同式);level_runner 两处改读表;:774-776/:888-890 过时注释随动订正 | 审计 §二 定点清单② | -| d12 | 产发端 `game/core/damage_controller.gd:168/370/400/504`+解析端 `game/presentation/views/battle_stage_view.gd:332-346`+`game/presentation/row_pacer.gd:110-115/135-143`+`game/presentation/views/standee_body.gd` | 结算行以 display_name 子串匹配(`_card_by_name` 的 `contains`)解析受击站桩——同名敌或名字互为前缀错位 | 产发端四处在行内**增键** `"target_id": <敌 enemy_id>`("target" 文本值保留——日志行文不变);standee_body 新增 `func enemy_id() -> String` 访问器;battle_stage_view 新增按键解析 `_card_by_id(enemy_id)`(相等匹配),`enemy_standee_center` 改签名(id 先、display_name 兜底);row_pacer 取 `row.get("target_id","")` 传入 | 审计 §二 定点清单③ | +| d9 | `game/presentation/modal_stack.gd:21-38` | `open()` 对未登记层(`_list.find(m)`=-1)静默隐藏全部已开层;同层重复 open 时第二次 `hidden` 为空表(上方已隐)→ `_occluded[m]` 被空表覆盖,原被隐藏层 close 后永不恢复 | fail-fast+遮挡账**合并非覆盖**:`open()` 首行 find<0 即 `push_error` 且 return;重复 open 仍重扫上方可见层(V6 遮挡语义不变——modal_flow_test :40-48 在役断言依赖之),`_occluded[m]` 改**旧账∪新隐去重合并**(吞账缺陷修复);`close()` 对未登记层 `push_error` | 审计 §二 C10(修法经 grilling A-2 订正:幂等直返方案与在役断言冲突,改合并制) | +| d10 | `game/core/minesweeper_rules.gd:8-9`+全库 28 处 | 两条核心信号零契约成文(违 code-conventions §2.1);全库信号注释载体 28 处 `#` 非 `##`(不进编辑器 F1 帮助;grilling 复算 28/51 精确吻合) | :8/:9 按 §2.1 三要素(参数语义〔载荷键集按发射位并集:cell_revealed 四处 :129/:303/:310/:345、seal_judged :476〕/发送时点/消费方依赖)补 `##` 契约;全库信号声明行的 `#` 注释逐处换 `##`(注释内容逐字保留) | 审计 §二 定点清单① | +| d11 | `game/core/level_runner.gd:779/895`+`game/data/schemas/shop_table.gd`+`game/data/tables/shop.tres`+`game/core/config_db.gd` | relic 基价 `15.0`(:895)与散折 `0.8`(:779)是玩法数值字面量(自注 provisional)——违数值单一事实源 | ShopTable 新增两个 knob:`relic_base_price: float = 15.0`(域 [1.0,99.0])+`spend_discount: float = 0.8`(域 (0.0,1.0]),`validate()` 补两域检;ConfigDB 新增 `shop_relic_base_price() -> float`/`shop_spend_discount() -> float`(:337-341 同式);level_runner 两处改读表;过时注释随动订正 | 审计 §二 定点清单② | +| d12 | 产发端 `game/core/damage_controller.gd:168/370/400/504`+解析端**两口** `game/presentation/views/battle_stage_view.gd:308(on_step_row_fx——闪白/火花/击杀灰化)与 :342-346(enemy_standee_center——弹道/标出)**+`game/presentation/row_pacer.gd:110-115/135-143`+`game/presentation/views/standee_body.gd` | 站桩解析两口都以 display_name 子串匹配(`_card_by_name` 的 `contains`,消费点 :308 与 :343——grilling A-3 订正:审计点名的「弹道/闪白/击杀」三症分住两口,v1.0 漏了 :308)——同名敌或名字互为前缀错位 | 产发端四处行内/载荷内**增键** `"target_id": <敌 enemy_id>`("target" 文本值保留——日志行文不变;:168/:400 属 fx 载荷面,其键是否随 fx 行下发到 :308 解析口=T0 核类);standee_body 新增 `func enemy_id() -> String`;battle_stage_view 新增 `_card_by_id(enemy_id)`(相等匹配),`enemy_standee_center` 改签名(id 先、display_name 兜底)、`on_step_row_fx` 解析同改(id 先、名兜底);row_pacer 取 `row.get("target_id","")` 传入 | 审计 §二 定点清单③ | | d13 | `game/core/treasure_items.gd:55-62` | 三段孤儿注释(持有数/持有件记录/丢弃)指向已删函数(连空壳都不在) | 三段孤儿注释删除 | 审计 §二 定点清单④ | | d14 | `game/core/board_generator.gd:97/334/281` | 目标雷数公式两处手抄(:97 与 :334 同式);`legality(b, params, db)` 的 db 参数未用 | 公式单点化(`static func` 一处、两调用点改引);`legality` 去 db 参数(调用点两处:board_generator.gd:53+tests/unit/core/board_gen_reward_test.gd:145,同批改) | 审计 §二 定点清单⑤ | -| d15 | `game/core/action_economy.gd:191-192` | 蓄力层上限 `3` 硬编码两处字面量(`mini(3,…)`/`>= 3`) | 模块常量 `const CHARGE_LAYER_CAP := 3`(机制常量非表值——结构常量先例 STANDEE_FOOT_MARGIN 同型);两处改引 | 审计 §二 定点清单⑥ | +| d15 | `game/core/action_economy.gd:191-192`(注释 :185 随动) | 蓄力层上限 `3` 硬编码两处字面量(`mini(3,…)`/`>= 3`);:185 注释「上限 3」同源 | 模块常量 `const CHARGE_LAYER_CAP := 3`(机制常量非表值——结构常量先例 STANDEE_FOOT_MARGIN 同型);两处+注释随动改引 | 审计 §二 定点清单⑥ | | d16a | `game/core/unit_container.gd:55`+`game/data/schemas/hero_table.gd`+`game/data/tables/hero.tres`+`game/core/config_db.gd` | 英雄名「探险者」硬编码绕开 HeroTable(敌人名走 row.display_name) | HeroTable 新增 `display_name: String = "探险者"`(非空域检);ConfigDB 新增 `hero_display_name() -> String`;unit_container:55 改读表 | 审计 §二 定点清单⑦ | | d16b | `game/core/unit_container.gd:257/270`+`game/core/status_container.gd:58-61/102/114` | Dictionary 取值 Variant 裸算术(`u.hp - n`/`u.hp += actual`/`inst.layers …`)漏包 int() | 逐处算术前显式 `int()` 包裹(写回路径保持既有语义) | 审计 §二 定点清单⑧ | | d17 | `game/presentation/views/settlement_fx_view.gd:94-95` | `await get_tree().process_frame` 后无 `is_instance_valid(lab)` 守卫(全库守卫惯例唯一漏网处) | await 后补 `if not is_instance_valid(lab): return` | 审计 §二 定点清单⑨ | @@ -45,59 +46,59 @@ **完成定义**(全部满足才算本批完成): 1. 钉值表 19 行落地(d16 拆 a/b 两行计);d11/d16a 表值与原字面量逐位一致(15.0/0.8/「探险者」),无数值调整、MC 零跑; -2. §8.2 对照表逐行断言绿+撤销证明双证齐(回退该单元 hunk → 对应断言红 → 还原复绿); -3. d10 载体统一后,`grep -rnE "^\s*signal\s+\w+\(.*\)\s*#(?!#)"`(-P)对 `game/` 全域零命中; -4. 批末按 `tools/run_all_gates.sh` 域口径选档(本批只碰 `game/`)全绿+改前改后读数对拍;三份 `reports/` 产出物写齐(T3)。 +2. §8.2 对照表逐行断言绿;**行为改动单元撤销证明双证齐**(回退该单元 hunk → 对应断言红 → 还原复绿——只撤销本批 hunk,禁注入/改值造红);**等价类单元如实申报**(d1 语义加固/d11/d16a 原值迁移/d13–d16/d18 等价重构——撤销不红属预期,以等价断言与读数对拍承载;d17 无独立断言以惯例一致性走查申报——见 §8.2 分行); +3. d10 载体统一后,`grep -rnP "^\s*signal\s+\w+\(.*\)\s*#(?!#)"` 对 `game/` 全域零命中; +4. 批末按 `tools/run_all_gates.sh` 域口径选档(本批只碰 `game/`,域划分唯一出处=脚本头注 :10-15)全绿(含 S13 基线零新增)+改前改后读数对拍;三份 `reports/` 产出物写齐(T3)。 ## 2. 设计事实源 | # | 出处 | 取用条款 | |---|---|---| -| D1 | 工程直入证据指认=审计报告 §二(C6–C10+已核实定点清单,2026-10-24 全目录只读审查)+本写卡会话逐处实查(§3 F1–F19) | 19 个改动单元的 file:line 现状与成因定性 | +| D1 | 工程直入证据指认=审计报告 §二(C6–C10+已核实定点清单)+本写卡会话逐处实查(§3 F1–F21,含对审计三处读数的订正:C6 可达性前提/d12 解析口单复/路径) | 19 个改动单元的 file:line 现状与成因定性 | | D2 | [code-conventions](../design/engineering/code-conventions.md) §2.1 | 每个跨类信号:参数语义、发送时点、消费方依赖必须在发送方 `##` 文档注释成文(d10 依据) | | D3 | [code-conventions](../design/engineering/code-conventions.md) §4+AGENTS.md 数值单一事实源红线 | 玩法数值只存 `data/tables/`(.tres)经 ConfigDB 单点读取(d11/d16 依据;d15 判机制常量的边界=结构常量先例 STANDEE_FOOT_MARGIN) | | D4 | [architecture](../design/engineering/architecture/architecture.md) 架构原则 5(fail-fast) | d9 push_error 早退依据(「层必须先 register 方可 open/close」已写在 modal_stack 头注,机器强制缺口本批补) | -| D5 | [test-conventions](../design/engineering/test-conventions.md) §6/§9.4 | 新增断言的拦截能力自证与行为改动的撤销证明;本卡执行口径=每单元撤销证明(回退 hunk→红)+新断言族判别力随撤销证明一并自证 | +| D5 | [test-conventions](../design/engineering/test-conventions.md) §9.4+2026-10-24 用户 P0 令(iter36-实现报告 §纪律变更段在案) | 行为改动验收只走撤销证明(回退本批 hunk→断言红),禁注入/改值造红实验;新断言判别力随所属改动的撤销证明一并自证,证不了的一律记「拦截能力未证」 | -## 3. 现状事实(2026-10-24 写卡会话主区实查;开工日 T0 复核行号) +## 3. 现状事实(2026-10-24 写卡会话实查+2026-10-25 grilling 独立补查;开工日 T0 复核行号) | # | 事实 | 出处 | |---|---|---| -| F1 | `_on_unit_died` 遍历 `_queue` 按 `t.source_unit == u` 置 `cancelled`——Dictionary `==` 在 Godot 4 为逐键内容比较;同种同拍生成、同待发技能、同池状态的双敌内容全同即触发误作废(「死亡即不动手」误伤存活敌);`flush()` :197-198 静默作废链在 | `game/core/damage_controller.gd:210-216` | +| F1 | `_on_unit_died` 遍历 `_queue` 按 `t.source_unit == u` 置 `cancelled`——Dictionary `==` 在 Godot 4 为逐键内容比较。**可达性(grilling 订正)**:`unit_container.gd:98` 敌单位行带 `"handle_id": handle`,handle 随实例自增(:77/:114)——任意两敌单位字典内容必异,真实 spawn 路径下 `==` 只对同一字典为真,误作废不可达;该行是语义隐患(判定语义应为引用同一性)而非现行行为缺陷 | `game/core/damage_controller.gd:210-216`;`game/core/unit_container.gd:77/98/114` | | F2 | 蓄力档判定链:`set_pending(ptype, pid)` :154;`pid in CHARGE_SKILL_IDS`(:7 `["heavy"]`)时 `col = UiKit.GOLD_INK`(:172,Color8(116,80,11));`_play_intent_motion` :182-194 判 `if _intent_col == UiKit.GOLD_DEEP`(:188,Color8(176,122,20))——常量错配,③蓄力缓推+定格微顿+回落分支 :189-191 恒不可达 | `game/presentation/views/standee_body.gd:7/154/171-172/182-194` | -| F3 | `GOLD_BRIGHT` 注释含「GOLD_DEEP 语义岗〔standee:199 意图判据/board_view:35/level_map:237〕在役不动」——standee 意图判据即 F2 死代码 | `game/presentation/views/ui_kit.gd:28` | -| F4 | `_play_celebrate` :281-287 `_cele.create_tween()`+`set_loops()`(无限)无句柄持有;`close()` :156-161 只置 visible=false+`_clear_crest_bricks()`,零 kill;`open_victory` :131 每调必 `_play_celebrate()`。全库先 kill 惯例先例=board_view:362-364(审计引) | `game/presentation/views/battle_end_overlay.gd:116-139/156-161/281-287` | +| F3 | `GOLD_BRIGHT` 注释含「GOLD_DEEP 语义岗〔standee:199 意图判据/board_view:35/level_map:237〕在役不动」——grilling 实查三处引述全失真(board_view:35=`DEPTH_PX`;level_map:237 在 abandon 确认段;两文件对 GOLD_DEEP/GOLD_BRIGHT 引用 grep 零命中) | `game/presentation/views/ui_kit.gd:28` | +| F4 | `_play_celebrate` :281-287 `_cele.create_tween()`+`set_loops()`(无限)无句柄持有;`close()` :156-161 只置 visible=false+`_clear_crest_bricks()`,零 kill;`open_victory` :131 每调必 `_play_celebrate()`。全库先 kill 惯例先例=board_view:362-364 | `game/presentation/views/battle_end_overlay.gd:116-139/156-161/281-287` | | F5 | `set_context_locked` :82-85 只置 `_dbg_btn.disabled = _ctx_locked`;`_sync_sim_button` :100-103 模拟钮看 `_sim_running or _ctx_locked`——同屏两钮判据不对称;`is_running()` :71-72 已有(面板态) | `game/presentation/views/debug_overlay.gd:71-103` | -| F6 | `_start_debug_levels` :712-717 守卫 `run_scope.is_adventure or run_scope.settlement != null`,:717 `debug_overlay.reset_sliders()`;批量模拟(tune_sim_controller.run 逐帧 await :58)与调试对局并发=演出扭曲+测量作废(autoplay 自建局部 RngService=`game/sim/level_autoplay.gd:44`,无全局 RNG 竞态——审计已核缓解面) | `game/presentation/main.gd:712-724` | +| F6 | `_start_debug_levels` :712-717 守卫 `run_scope.is_adventure or run_scope.settlement != null`,:717 `debug_overlay.reset_sliders()`;批量模拟(tune_sim_controller.run 逐帧 await :58)与调试对局并发=演出扭曲+测量作废(autoplay 自建局部 RngService=`game/sim/level_autoplay.gd:44`,无全局 RNG 竞态) | `game/presentation/main.gd:712-724` | | F7 | `_on_tune_simulate` :1486-1491 守卫只 `run_scope.settlement != null`;`_tune_sim` 构造点 :393(无 driver 注入) | `game/presentation/main.gd:393/1486-1491` | | F8 | `TuneSimController` 零运行态查询面:`run(n)` :30-62 唯一执行体(`panel.set_sim_running(true)` :37 ↔ `:62`);RefCounted,`_init(db_ref, panel_ref, base_hp: int, driver = null)` 有 driver 注入位 | `game/presentation/tune_sim_controller.gd:16-62` | -| F9 | `open()` :21-30:`idx := _list.find(m)` 为 -1 时 `range(idx+1, size)` 隐藏**全部**已开层后 `_occluded[m] = hidden`、`m.visible = true`;同层重复 open 时第二次 `hidden` 为空表(上方已隐)→ `_occluded[m]` 被空表覆盖,原被隐藏层 close 后永不恢复;`close()` :33-38 对未登记层无防护。当前调用面无违规者=埋雷非现症 | `game/presentation/modal_stack.gd:21-38` | -| F10 | `cell_revealed`(:8)与 `seal_judged`(:9)零注释;同文件 `round_end_board`(:10)带 `#` 注释;全库信号声明行携 `#`(非 `##`)注释 28 处/声明总数 51(2026-10-24 实数);发射位:cell_revealed ×4(:129/:303/:310/:345)、seal_judged ×1(:476 `{"cell": c, "hit": …}`)。**路径订正**:卡②所引 hud_presenter 实址 `game/presentation/hud_presenter.gd`(非 views/) | `game/core/minesweeper_rules.gd:8-10`;全库 grep 实数 | -| F11 | 散折单点 `_spend_discounted` :777-780 `maxi(1, int(floor(float(price) * 0.8)))`;relic 基价 :895 `int(ceil(15.0 * pow(db.shop_price_b(), …) * pow(db.shop_price_a(), …)))`;两处注释自注 provisional/「shop.tres 词表扩列归数值批」。ShopTable 标量 knob 先例:`price_a`/`price_b`(:13-14,域检 :101-104);`SHELF_KINDS` 封闭词表 :18 不含 relic(relic=池令牌非货架种——扩词表属设计裁);ConfigDB shop 访问器族 :304-341 | `game/core/level_runner.gd:769-780/888-900`;`game/data/schemas/shop_table.gd:13-18/101-104`;`game/core/config_db.gd:304-341` | -| F12 | 站桩解析链:`_card_by_name(display_name)` :332-338 以 `c.display_name().contains(display_name)` 子串匹配;`enemy_standee_center(display_name)` :342-346 唯一出口;消费端 row_pacer 两处(:110-115 结算标出、:135-143 跨区弹道)取 `row.get("target","")`;产发端四处在行内携敌方 display_name(`"target"` 键):damage_controller :168(attack_commit fx 载荷)、:370(fx payload)、:400(kill hits)、:504(damage 行);哨兵值 `"hero"`(:470/:527、orchestrator:885)与 `"all_enemies"`(:519)不经站桩解析或走 `hero_standee_center`;单位字典带 `enemy_id`(unit_container:99 敌/:55 英雄 `"hero"`);standee 有 `display_name()` 访问器(:65)与 `_enemy_id` 成员(:44/:89 装载),**无 enemy_id 访问器** | `game/presentation/views/battle_stage_view.gd:332-346`;`game/presentation/row_pacer.gd:106-150`;`game/core/damage_controller.gd:168/370/400/470/504/519/527`;`game/core/unit_container.gd:55/99`;`game/presentation/views/standee_body.gd:44/65/89` | -| F13 | treasure_items :55-58「持有数」注释段与 :61-62「持有件记录/丢弃」注释段之间零函数体(描述的函数已删净,:66 起才是 `_usable_now`) | `game/core/treasure_items.gd:51-66` | -| F14 | 雷数公式 :97(生成期)与 :334(产物断言期)同式手抄 `int(round(params.density * float(params.w * params.h - SPAWN_AREA_CELLS)))`;`legality(b, params, db)` :281-283 db 参数未用(行内带 `# type-hint: ignore` 豁免),调用点两处 | `game/core/board_generator.gd:53/97/281-283/334`;`game/tests/unit/core/board_gen_reward_test.gd:145` | -| F15 | `finish_round_stop` :188-196 内 `mini(3, _charge_layers + _last_stop_ap)`(:191)与 `_charge_layers >= 3`(:192) | `game/core/action_economy.gd:188-196` | -| F16 | 英雄单位构造硬编码 `"display_name": "探险者"`;HeroTable 现仅三数值轴(max_hp/atk/armor_class,零文案字段);敌名走 `row.display_name` | `game/core/unit_container.gd:55`;`game/data/schemas/hero_table.gd:8-10` | +| F9 | `open()` :21-30:`idx := _list.find(m)` 为 -1 时 `range(idx+1, size)` 隐藏**全部**已开层后 `_occluded[m] = hidden`、`m.visible = true`;同层重复 open 时第二次 `hidden` 为空表(上方已隐)→ `_occluded[m]` 被空表覆盖,原被隐藏层 close 后永不恢复;`close()` :33-38 对未登记层无防护。**在役断言约束(grilling 查出)**:`modal_flow_test.gd:40-48` V6 序列 open(a)→open(map)→open(a) 断言 `not map.visible`——依赖「重复 open 仍重扫上方」,幂等直返方案会使该断言变红(d9 采合并制的依据) | `game/presentation/modal_stack.gd:21-38`;`game/tests/unit/presentation/modal_flow_test.gd:40-48` | +| F10 | `cell_revealed`(:8)与 `seal_judged`(:9)零注释;同文件 `round_end_board`(:10)带 `#` 注释;全库信号声明行携 `#`(非 `##`)注释 28 处/声明总数 51(本会话与 grilling 双重 `grep -P` 复算一致);发射位:cell_revealed ×4(:129/:303/:310/:345)、seal_judged ×1(:476 `{"cell": c, "hit": …}`) | `game/core/minesweeper_rules.gd:8-10`;全库 grep 实数 | +| F11 | 散折单点 `_spend_discounted` :777-780 `maxi(1, int(floor(float(price) * 0.8)))`;relic 基价 :895 `int(ceil(15.0 * pow(...)))`。ShopTable 标量 knob 先例:`price_a`/`price_b`(:13-14,域检 :101-104);`SHELF_KINDS` 封闭词表 :18 不含 relic(relic=池令牌非货架种);ConfigDB shop 访问器族 :304-341 | `game/core/level_runner.gd:769-780/888-900`;`game/data/schemas/shop_table.gd:13-18/101-104`;`game/core/config_db.gd:304-341` | +| F12 | 站桩解析**两口**(grilling 订正):`on_step_row_fx` :308 用 `_card_by_name(target)` 解析受击站桩(闪白 :311→`_schedule_arrival_fx` :318-325 火花/击杀灰化)+`enemy_standee_center` :342-346(row_pacer :110-115 结算标出、:135-143 跨区弹道消费);`_card_by_name` :332-338 以 `contains` 子串匹配。产发端四处携 display_name:damage_controller :168(attack_commit fx **载荷**)、:370(fx 载荷)、:400(kill hits 载荷)、:504(damage **行**);哨兵 `"hero"`(:470/:527、orchestrator:885)与 `"all_enemies"`(:519)不经站桩解析;单位字典带 `enemy_id`(unit_container:99 敌/:55 英雄 `"hero"`);standee 有 `display_name()`(:65)与 `_enemy_id`(:44/:89 装载),**无 enemy_id 访问器** | `game/presentation/views/battle_stage_view.gd:308-346`;`game/presentation/row_pacer.gd:106-150`;`game/core/damage_controller.gd:168/370/400/470/504/519/527`;`game/core/unit_container.gd:55/99`;`game/presentation/views/standee_body.gd:44/65/89` | +| F13 | treasure_items :55-58「持有数」注释段与 :61-62「持有件记录/丢弃」注释段之间零函数体(:66 起才是 `_usable_now`) | `game/core/treasure_items.gd:51-66` | +| F14 | 雷数公式 :97(生成期)与 :334(产物断言期)同式手抄;`legality(b, params, db)` :281-283 db 参数未用(行内带 `# type-hint: ignore` 豁免),调用点两处 | `game/core/board_generator.gd:53/97/281-283/334`;`game/tests/unit/core/board_gen_reward_test.gd:145` | +| F15 | `finish_round_stop` :188-196 内 `mini(3, _charge_layers + _last_stop_ap)`(:191)与 `_charge_layers >= 3`(:192);:185 注释含「上限 3」 | `game/core/action_economy.gd:185-196` | +| F16 | 英雄单位构造硬编码 `"display_name": "探险者"`;HeroTable 现仅三数值轴(零文案字段);敌名走 `row.display_name` | `game/core/unit_container.gd:55`;`game/data/schemas/hero_table.gd:8-10` | | F17 | Variant 裸算术:unit_container :257(`u.hp - n`)、:270(`u.hp += actual`);status_container :58-61(`inst.layers` 比较/自增)、:102(`inst.layers * inst.snap_m`)、:114(`inst.remaining -= 1`) | `game/core/unit_container.gd:250-271`;`game/core/status_container.gd:56-64/100-119` | | F18 | `play_damage_number` :94 `await get_tree().process_frame` 后 :95 直取 `lab.size`——lab 在等待帧间释放即错;全库 await 后守卫惯例(如 `_schedule_arrival_fx` :318-329) | `game/presentation/views/settlement_fx_view.gd:85-99` | -| F19 | `_normalize_floor_luma` static,`lumas_out = null` 无类型;调用点三处(board_view:957 传 `var lumas: Array[Variant] = []`、terrain_tile_sets_test:135、ui_contrast_probe:150 传 null) | `game/presentation/views/board_view.gd:950-998`;`game/tests/unit/presentation/terrain_tile_sets_test.gd:135`;`game/probe/ui_contrast_probe.gd:150` | -| F20 | 断言宿主在役实况:damage_controller_test(直构 ConfigDB/RngService/UnitContainer/StatusContainer/DamageController,已覆盖「死亡作废」面);modal_flow_test(直构 ModalStack+哑 Control);level_shop_economy_test(商店域);pacing_queue_test(row_pacer 排播域);system_test(真实玩法路径宿主);单测入闸协议=run_all.gd 套件清单显式登记行 | `game/tests/unit/battle_settlement/damage_controller_test.gd:9-30`;`game/tests/unit/presentation/modal_flow_test.gd:1-20`;`game/tests/run_all.gd`(清单 :91/:101 先例) | +| F19 | `_normalize_floor_luma` static,`lumas_out = null` 无类型;调用点三处(board_view:957 传 `Array[Variant]`、terrain_tile_sets_test:135、ui_contrast_probe:150 传 null) | `game/presentation/views/board_view.gd:950-998`;`game/tests/unit/presentation/terrain_tile_sets_test.gd:135`;`game/probe/ui_contrast_probe.gd:150` | +| F20 | 断言宿主在役实况:damage_controller_test(直构 ConfigDB/RngService/UnitContainer/StatusContainer/DamageController,已覆盖「死亡作废」面);modal_flow_test(直构 ModalStack+哑 Control,:40-48 V6 序列在役);level_shop_economy_test(商店域);pacing_queue_test(row_pacer 排播域);system_test(真实玩法路径宿主);单测入闸协议=run_all.gd 套件清单显式登记行。**脚本错判定面**:单件直跑退出码不含运行期脚本错——判红须经 `tools/error_scan.py` 扫直跑输出(run_all.gd:136 同款机制) | `game/tests/unit/battle_settlement/damage_controller_test.gd:9-30`;`game/tests/unit/presentation/modal_flow_test.gd:1-48`;`game/tests/run_all.gd:91/:101/:136` | | F21 | 改前读数基线=开工日 T0 采集(写卡会话不跑测——测试执行两入口铁规),本卡不预写通过数 | — | ## 4. 设计契约(红线,违反 = L3 停机呈报) -🔴 **契约 1 · 钉值表逐字**:§1 钉值表 19 行逐字落地;d11/d16a 为**原值迁移**(15.0/0.8/「探险者」),禁顺带调值禁增减字段语义;d2 是修成 [战斗表现](../design/gdd/systems/战斗循环/战斗表现.md) §4.6.4 已成文的三档运动签名(激活死代码=对齐设计,非新设计);d12 行内**只增键不改值**("target" 的 display_name 文本保留——战斗日志行文零变化)。 +🔴 **契约 1 · 钉值表逐字**:§1 钉值表 19 行逐字落地;d11/d16a 为**原值迁移**(15.0/0.8/「探险者」),禁顺带调值禁增减字段语义;d2 是修成 [战斗表现](../design/gdd/systems/战斗循环/战斗表现.md) §4.6.4 已成文的三档运动签名(激活死代码=对齐设计);d12 行内/载荷内**只增键不改值**("target" 的 display_name 文本保留——日志行文零变化)。 -🔴 **契约 2 · core 触碰面封闭清单**:core 文件改动全部为钉值表所列定点(damage_controller 一处判定符+四处增键、minesweeper 两行契约、level_runner 读表替换+注释订正、board_generator 公式单点+去参、action_economy 常量化、unit_container 读表+int() 包裹、status_container int() 包裹、treasure_items 注释删)——**battle_orchestrator 零触碰**(⑦头注归条目④;orchestrator:718 treasure_used 行的 target 形态 T0 核类,若为敌 display_name 则同批增键,属 d12 产发端清单的 T0 扩面非新单元);零编排逻辑、零结算序、零随机流改动。 +🔴 **契约 2 · core 触碰面封闭清单**:core 文件改动全部为钉值表所列定点(damage_controller 一处判定符+四处增键、minesweeper 两行契约、level_runner 读表替换+注释订正、board_generator 公式单点+去参、action_economy 常量化+注释随动、unit_container 读表+int() 包裹、status_container int() 包裹、treasure_items 注释删)——**battle_orchestrator 零触碰**(⑦头注归条目④;orchestrator:718 treasure_used 行的 target 形态 T0 核类,若为敌 display_name 则同批增键,属 d12 产发端清单的 T0 扩面非新单元);零编排逻辑、零结算序、零随机流改动。 -🔴 **契约 3 · 表扩列纪律**:ShopTable/HeroTable 新字段全部带 `validate()` 域检(F11/F16 既有条目同式);消费面一律经 ConfigDB 新访问器;两表 .tres 值域注释随批补;跨表校验器(`config_db_cross_validator.gd`)是否需登记新字段=T0 核(其只校键集的域不涉新标量则零改动)。 +🔴 **契约 3 · 表扩列纪律**:ShopTable/HeroTable 新字段全部带 `validate()` 域检(F11/F16 既有条目同式);消费面一律经 ConfigDB 新访问器;跨表校验器(`config_db_cross_validator.gd`)是否需登记新字段=T0 核(其只校键集的域不涉新标量则零改动)。 -🔴 **契约 4 · 验收闭合**:19 单元每单元一行 §8.2 对照表行,断言+撤销证明双证;「只改判定符/注释/类型就写已实现」不成立;撤销证明=精确回退该单元 hunk → 最窄闸红 → 还原复绿(最窄闸=接口块逐族命令)。 +🔴 **契约 4 · 验收闭合与证明纪律(2026-10-24 P0 令)**:行为改动单元(d2/d4/d5/d6/d7/d8/d9/d12/d10-契约半)撤销证明=**只回退本批该单元 hunk** → 最窄闸对应断言红 → 还原复绿;**禁注入造红、禁改值造红**(等价类单元 d1/d11/d13–d18 撤销不红属预期,如实申报、以等价断言与读数对拍承载);断言判别力证不了的面一律记「拦截能力未证」,禁硬凑。 -🔴 **契约 5 · 断言面零未申报削弱**:既有断言零删除零放宽;d14 改 board_gen_reward_test:145 调用签名属**随签名同批改**(非削弱,申报在案);新增断言全列 §8.2。 +🔴 **契约 5 · 断言面零未申报削弱**:既有断言零删除零放宽;**d9 修法与 modal_flow_test :40-48 V6 在役断言必须同绿**(合并制设计的硬约束);d14 改 board_gen_reward_test:145 调用签名属随签名同批改(非削弱,申报在案);新增断言全列 §8.2。 -🔴 **契约 6 · golden 判定先于动作**:d1/d2/d12 是行为修正,渲染闸棋盘三图可能 changed(同内容双敌局/蓄力敌局/同名敌局的弹道与意图演出变化=修对的证据而非回归);本批不预重制,按 [golden README](../game/tests/golden/README.md) 双态判定(判有效加注;判失效显式呈报后重制+复闸);菜单基线预期无涉。 +🔴 **契约 6 · golden 判定先于动作**:d2/d12 是行为修正,渲染闸棋盘三图可能 changed(蓄力敌局/同名敌局的意图与弹道演出变化=修对的证据而非回归);本批不预重制,按 [golden README](../game/tests/golden/README.md) 双态判定(判有效加注;判失效显式呈报后重制+复闸);菜单基线预期无涉。 🔴 **契约 7 · d10 注释逐字保留**:28 处信号注释只换载体 `#`→`##`,注释内容逐字不动(含旧词——用语清扫另有其批);minesweeper 两契约新写成文按 §2.1 三要素,载荷键集以发射位实查并集为准(T0 复核四处发射位键集后落笔)。 @@ -119,7 +120,7 @@ | 文档 | 关联点 | 同步义务 | |---|---|---| | [战斗结算](../design/gdd/systems/战斗循环/战斗结算.md) 明细行协议节 | d12 行内增 `target_id` 键=行协议字段集扩列(T0 查该节是否逐键登记行字段,列则补一行) | 反哺点 · 列清单(①增键说明+依据=本卡 d12;呈现消费语义不变) | -| [存档序列化](../design/gdd/systems/表现与支撑/存档序列化.md)/[行动经济](../design/gdd/systems/排雷循环/行动经济.md)/[战斗表现](../design/gdd/systems/战斗循环/战斗表现.md)/shop 相关 GDD | d11/d15/d16 值未变仅迁源、d2 对齐已成文设计——2026-10-24 写卡会话检索(散折/基价/蓄力层/英雄名关键词)零陈述被本批改变 | 无关联文档(查讫) | +| [存档序列化](../design/gdd/systems/表现与支撑/存档序列化.md)/[行动经济](../design/gdd/systems/排雷循环/行动经济.md)/[战斗表现](../design/gdd/systems/战斗循环/战斗表现.md)/shop 相关 GDD | d11/d15/d16 值未变仅迁源、d2 对齐已成文设计——写卡会话检索(散折/基价/蓄力层/英雄名关键词)零陈述被本批改变 | 无关联文档(查讫) | | `待办清单.md` | 来源条目批后按拆分结论退役/换代(归 batch-closure) | 反哺点 · 列清单(②批末退役笔) | | `roadmap.md` | 迭代行编入笔(归 iter-plan 段发令) | 反哺点 · 列清单(③) | | `game/data/tables/shop.tres`/`hero.tres`、`game/tests/`、探针与单测文件 | 实施本体与断言面 | 实施本体(可写) | @@ -132,92 +133,92 @@ | 文件 | 职责 | 行为改动 | |---|---|---| -| `game/core/damage_controller.gd` | d1 判定符+d12 四处增键(复用既有·修改) | 行为改动 → wd1/wd12 | +| `game/core/damage_controller.gd` | d1 判定符+d12 四处增键(复用既有·修改) | d1 非行为改动(语义加固)→ wd1;d12 行为改动 → wd12 | | `game/presentation/views/standee_body.gd` | d2 `_intent_charge` 布尔分档+d12 `enemy_id()` 访问器(复用既有·修改) | 行为改动 → wd2/wd12 | | `game/presentation/views/ui_kit.gd` | d3 注释订正一行(复用既有·修改) | 非行为改动(注释)→ 随 wd2 复核 | | `game/presentation/views/battle_end_overlay.gd` | d4 tween 句柄 kill 纪律(复用既有·修改) | 行为改动 → wd4 | | `game/presentation/views/debug_overlay.gd` | d5 调试钮判据并入模拟运行态(复用既有·修改) | 行为改动 → wd5 | | `game/presentation/main.gd` | d6/d7 两守卫补口(复用既有·修改) | 行为改动 → wd6/wd7 | | `game/presentation/tune_sim_controller.gd` | d8 `is_running()` 运行态查询面(复用既有·增成员) | 行为改动 → wd8 | -| `game/presentation/modal_stack.gd` | d9 fail-fast 三早退(复用既有·修改) | 行为改动 → wd9 | +| `game/presentation/modal_stack.gd` | d9 fail-fast+遮挡账合并制(复用既有·修改) | 行为改动 → wd9 | | `game/core/minesweeper_rules.gd`+全库 28 信号行 | d10 两契约成文+载体统一(复用既有·修改) | wd10(契约成文=行为改动·注释面;载体统一=非行为改动) | -| `game/data/schemas/shop_table.gd`+`game/data/tables/shop.tres`+`game/core/config_db.gd` | d11 两 knob+域检+访问器(复用既有·扩列) | 行为改动(读数源迁移)→ wd11 | -| `game/core/level_runner.gd` | d11 两处读表+注释订正(复用既有·修改) | 行为改动 → wd11 | -| `game/presentation/views/battle_stage_view.gd`+`game/presentation/row_pacer.gd` | d12 按 id 解析+target_id 取用(复用既有·修改) | 行为改动 → wd12 | -| `game/core/treasure_items.gd` | d13 孤儿注释删(复用既有·删注释) | 非行为改动 → wd13 静态半 | +| `game/data/schemas/shop_table.gd`+`game/data/tables/shop.tres`+`game/core/config_db.gd` | d11 两 knob+域检+访问器(复用既有·扩列) | 等价类(读数源迁移)→ wd11 | +| `game/core/level_runner.gd` | d11 两处读表+注释订正(复用既有·修改) | 等价类 → wd11 | +| `game/presentation/views/battle_stage_view.gd`+`game/presentation/row_pacer.gd` | d12 两口按 id 解析+target_id 取用(复用既有·修改) | 行为改动 → wd12 | +| `game/core/treasure_items.gd` | d13 孤儿注释删(复用既有·删注释) | 非行为改动 → wd13 | | `game/core/board_generator.gd` | d14 公式单点+legality 去参(复用既有·修改) | 非行为改动(等价重构)→ wd14 | -| `game/core/action_economy.gd` | d15 常量化(复用既有·修改) | 非行为改动 → wd15 | -| `game/data/schemas/hero_table.gd`+`game/data/tables/hero.tres`+`game/core/config_db.gd`+`game/core/unit_container.gd` | d16a 英雄名入表(扩列);d16b int() 包裹 | wd16(读数源迁移)/非行为改动 | +| `game/core/action_economy.gd` | d15 常量化+注释随动(复用既有·修改) | 非行为改动 → wd15 | +| `game/data/schemas/hero_table.gd`+`game/data/tables/hero.tres`+`game/core/config_db.gd`+`game/core/unit_container.gd` | d16a 英雄名入表(扩列);d16b int() 包裹 | wd16 等价类/非行为改动 | | `game/core/status_container.gd` | d16b int() 包裹四处(复用既有·修改) | 非行为改动 → 随 wd16 | | `game/presentation/views/settlement_fx_view.gd` | d17 await 后守卫(复用既有·修改) | 行为改动(健态)→ wd17 | | `game/presentation/views/board_view.gd` | d18 参数类型(复用既有·修改) | 非行为改动 → wd18 | -| `game/tests/unit/battle_settlement/damage_controller_test.gd` | d1 断言扩展(同内容双敌作废面)(复用既有·增断言) | 断言面 → wd1/wd12 产发半 | +| `game/tests/unit/battle_settlement/damage_controller_test.gd` | d1 语义断言+d12 产发断言(复用既有·增断言) | 断言面 → wd1/wd12 | | `game/tests/unit/presentation/standee_fx_sweep_test.gd` | **新增**:d2 意图档分档+d4 句柄 kill+d12 按 id 解析三断言族(形制=SceneTree+test_kit,同 modal_flow_test;新增·新文件) | 断言面 → wd2/wd4/wd12 呈现半 | -| `game/tests/unit/presentation/modal_flow_test.gd` | d9 三早退断言扩展(复用既有·增断言) | 断言面 → wd9 | +| `game/tests/unit/presentation/modal_flow_test.gd` | d9 三早退+合并制断言扩展(复用既有·增断言;:40-48 V6 序列原样保留同绿) | 断言面 → wd9 | | `game/tests/unit/core/level_shop_economy_test.gd` | d11 断言扩展(复用既有·增断言) | 断言面 → wd11 | | `game/tests/unit/presentation/pacing_queue_test.gd` | d12 排播链 target_id 优先断言(复用既有·增断言;夹具形态 T0 复核) | 断言面 → wd12 排播半 | | `game/tests/unit/core/board_generator_test.gd` | d14 同值断言+调用签名同批改(复用既有·增/改断言——签名变更已申报契约 5) | 断言面 → wd14 | -| `game/tests/system_test.gd` | d6/d7 守卫两断言(真实玩法路径)(复用既有·增断言) | 断言面 → wd6/wd7 | +| `game/tests/system_test.gd` | d6/d7 守卫两断言(复用既有·增断言) | 断言面 → wd6/wd7 | | `game/tests/run_all.gd` | 新套件清单登记行(复用既有·增行) | 断言面接线 | | `reports/iter-实现报告/代拍板追认单/反哺点`(三份,批末写) | 产出物落位(含 golden 判定读数) | 非行为改动 → wd19 | ### 接口块(全卡共用) -- 新成员/新函数签名(断言与撤销证明引用以此为准): +- 新成员/新函数签名(断言与撤销证明引用以此为准;**全类型含返回类型**): - `standee_body.gd`:`var _intent_charge := false`;`func enemy_id() -> String`。 - `battle_end_overlay.gd`:`var _celebrate_tw: Tween`。 - `tune_sim_controller.gd`:`var _running := false`;`func is_running() -> bool`。 - - `battle_stage_view.gd`:`func _card_by_id(enemy_id: String) -> Node2D`(`_cards` 内 `c.enemy_id() == enemy_id` 相等匹配);`enemy_standee_center(target_id: String, display_name: String)` 改签名(id 先、名兜底)。 + - `battle_stage_view.gd`:`func _card_by_id(enemy_id: String) -> Node2D`(`_cards` 内 `c.enemy_id() == enemy_id` 相等匹配);`func enemy_standee_center(target_id: String, display_name: String) -> Variant`(id 先、名兜底;现行同位函数本无返回类型——新签名补 `-> Variant`,卡②落地后 S9 R2 面零新增)。 - `config_db.gd`:`func shop_relic_base_price() -> float`/`func shop_spend_discount() -> float`/`func hero_display_name() -> String`。 - `shop_table.gd`:`@export var relic_base_price: float = 15.0`+`@export var spend_discount: float = 0.8`(validate 域检两条);`hero_table.gd`:`@export var display_name: String = "探险者"`(非空域检)。 - - `board_generator.gd`:`static func target_mine_count(params) -> int`(命名 L1 可调);`legality(b: BoardData, params: Dictionary) -> bool`(去 db 参)。 + - `board_generator.gd`:`static func target_mine_count(params: Dictionary) -> int`(命名 L1 可调);`legality(b: BoardData, params: Dictionary) -> bool`(去 db 参)。 - `action_economy.gd`:`const CHARGE_LAYER_CAP := 3`。 - row_pacer 两处取用改:`var target_id := String(row.get("target_id", ""))`+`stage.enemy_standee_center(target_id, target)`。 - 新单测形制:`standee_fx_sweep_test.gd`=`extends SceneTree`+`const Kit := preload("res://tests/unit/test_kit.gd")`+`_init()` 逐断言+`quit(Kit.finish(...))`(modal_flow_test 同构);run_all 清单行 `{"path": "res://tests/unit/presentation/standee_fx_sweep_test.gd", "expect": 0}`。 -- 最窄闸(撤销证明跑法): - - 单测族=`D:\code\godot\Godot_v4.7.2-stable_win64_console.exe --headless --path game --script res://tests/unit/<相对路径>.gd` 单件直跑; +- 最窄闸(撤销证明跑法与判红口径): + - 单测族=`D:\code\godot\Godot_v4.7.2-stable_win64_console.exe --headless --path game --script res://tests/unit/<相对路径>.gd` 单件直跑;**运行期脚本错判红=直跑输出经 `tools/error_scan.py` 扫出 SCRIPT ERROR 标记**(F20——单件退出码不含脚本错,d2/d8 撤销半依赖此口径); - 系统测试=`python tools/run_system_test.py`; - - 信号载体扫描=完成定义 3 的 grep -P 命令零命中; + - 信号载体扫描=完成定义 3 的 `grep -rnP` 命令零命中; - 类型面=`python tools/audit_type_hints.py`(判据=d18 行零命中+新增码零新增红)。 ### 落位与可复用性预检(本批新增件逐条三问) -- **`standee_fx_sweep_test.gd`(新单测文件)**——复用面:d9/d11/d14 各归域既有宿主(modal_flow/level_shop_economy/board_generator_test,F20);d1 归 damage_controller_test;d6/d7 归 system_test;d12 排播半归 pacing_queue_test;d2/d4/d12-站桩解析半三件同属「战斗舞台呈现域」且全库无 standee/battle_end/stage 宿主(2026-10-24 实查 tests/ 树)——并入任一现役文件都域错位,新立=该域唯一断言宿主。唯一面:与 type_glow_test(墨色投影域)扫域不交。分层与交互面:纯呈现层直建(StandeeBody/BattleEndOverlay/BattleStageView 均 `preload().new()` 直构、零场景文件依赖——theme_projection_test:200 BoardView 直建先例同构)。 +- **`standee_fx_sweep_test.gd`(新单测文件)**——复用面:d9/d11/d14 各归域既有宿主(modal_flow/level_shop_economy/board_generator_test,F20);d1 归 damage_controller_test;d6/d7 归 system_test;d12 排播半归 pacing_queue_test;d2/d4/d12-站桩解析半三件同属「战斗舞台呈现域」且全库无 standee/battle_end/stage 宿主(实查 tests/ 树)——并入任一现役文件都域错位,新立=该域唯一断言宿主。唯一面:与 type_glow_test(墨色投影域)扫域不交。分层与交互面:纯呈现层直建(StandeeBody/BattleEndOverlay/BattleStageView 均 `preload().new()` 直构、零场景文件依赖——theme_projection_test:200 BoardView 直建先例同构)。 - **ConfigDB 三个新访问器+两表三字段**——复用面:标量 knob+域检+访问器三件套是 ShopTable.price_a/price_b 既有形态(F11),照式扩展即复用;为什么不并入他表:relic 基价与散折都是商店域 knob、英雄名是英雄基线面——落点各归其主无第二候选。唯一面:三值各只此一处表内定义,level_runner/unit_container 字面量随批消亡。分层:数值只经 ConfigDB 单点读取(D3)。 -- **产品码 18 处修改**——零新增文件;新增函数仅访问器×2+常量×1+`_card_by_id`(为什么新增:按键解析与按名解析是两条判据,合一则旧路无兜底;与 `_card_by_name` 同文件同职责域无散落)。 +- **产品码 18 处修改**——零新增文件;新增函数仅访问器×3+常量×1+`_card_by_id`(为什么新增:按键解析与按名解析是两条判据,合一则旧路无兜底;与 `_card_by_name` 同文件同职责域无散落)。 - **d14 `target_mine_count` static 函数**——为什么新增:两处手抄公式的唯一收口点;不能复用现成:全库该式仅此两处无第三处共享面。 ### T0 事实坐实(≈0.25d) -- [ ] 复核 §3 全部 file:line(重点:d12 产发端四址+orchestrator:718 treasure_used 行 target 值形态核类——若为敌 display_name 增列 d12 第五址〔L2 记录〕;pacing_queue_test 夹具形态;ui_kit:28 所引 board_view:35/level_map:237 是否仍用 GOLD_DEEP;28 处信号载体清单逐处过目确认零误匹配)。可核查结果:行号漂移清单(零漂移则声明)进实现报告素材。 +- [ ] 复核 §3 全部 file:line(重点:d12 产发端四址+orchestrator:718 treasure_used 行 target 值形态核类+:168/:400 fx 载荷键是否下发到 :308 解析口——判 target_id 增键的必要位点;pacing_queue_test 夹具形态;28 处信号载体清单逐处过目确认零误匹配)。可核查结果:行号漂移清单(零漂移则声明)进实现报告素材。 - [ ] 采集改前读数基线(单测/系统测试通过数)。可核查结果:基线读数在案。 ### T1 core 域缺陷修+断言(≈1–1.25d) -- [ ] 实装 d1(is_same)+damage_controller_test 扩展断言:构造内容全同双敌 A/B(同 enemy 行、同待发技能、池状态一致),A 开单(enemy_skill 单据 source_unit=A)→ B 死亡事件 → 断言 A 单据**未**被作废;A 死亡 → A 单据作废(正向对照)。可核查结果:断言绿。 +- [ ] 实装 d1(is_same)+damage_controller_test 扩展语义断言:**手工构造**内容全同双敌字典 A/B(复刻单位字典键集但不含 handle_id——生产不可达的语义面用夹具钉住),A 开单(source_unit=A)→ B 死亡事件 → 断言 A 单据未作废;A 死亡 → A 单据作废(正向对照)。可核查结果:断言绿。 - [ ] 实装 d11(两 knob+域检+访问器+level_runner 读表+注释订正)+level_shop_economy_test 扩展断言:`db.shop_relic_base_price() == 15.0`、`db.shop_spend_discount() == 0.8`(经 ConfigDB 真装载)+pool_price("relic") 同种子同输入现价与改前逐位一致(等价证明)。可核查结果:断言绿。 - [ ] 实装 d16a(HeroTable.display_name+域检+访问器+unit_container:55 读表)+断言:`db.hero_display_name() == "探险者"`+spawn 后英雄单位 display_name 取值同。可核查结果:断言绿。 -- [ ] 实装 d15(常量化两处)+d16b(int() 包裹六处)+d14(公式单点+legality 去参+两调用点改)+board_generator_test 同值断言(`target_mine_count` 与原式同参同值)+调用签名同批改。可核查结果:单测绿。 +- [ ] 实装 d15(常量化两处+注释随动)+d16b(int() 包裹六处)+d14(公式单点+legality 去参+两调用点改)+board_generator_test 同值断言(`target_mine_count` 与原式同参同值)+调用签名同批改。可核查结果:单测绿。 - [ ] 实装 d10(minesweeper 两契约+全库 28 处载体统一)。可核查结果:完成定义 3 grep 读数零。 - [ ] 实装 d13(孤儿注释删)。可核查结果::51-66 段注释与函数体对齐。 -- [ ] 撤销证明(回退 hunk→最窄闸红→精确还原→记录;最窄闸=接口块单测直跑):①回退 d1 → 双敌断言红;②改 .tres 值(15.0→16.0)→ 表读断言红(证明断言钉在表值上)+还原;③回退 d16a 读表 hunk → 取值断言红;④回退 d10 契约 → grep 命中 2 处红。记录表进实现报告。 -- [ ] 验收步骤:T 段出口跑一次全套闸(按域选档,本批只碰 `game/`),期望全绿+11 号闸 NEED-APPROVAL 留痕(触 face=data/tables+damage_controller,§0)。 +- [ ] 撤销证明(**只回退本批 hunk**→最窄闸红→精确还原→记录;最窄闸=接口块单测直跑+error_scan 判红口径):①回退 d1 hunk(is_same 回 `==`)→ 双敌夹具断言红(B 死亡误废 A 单据);②回退 d10 契约 hunk → grep 命中 2 处红。等价类申报:d11/d16a/d14/d15/d16b/d13 撤销不红属预期(值等价/等价重构),以等价断言+改前改后读数对拍承载,记录表如实标注。记录表进实现报告。 +- [ ] 验收步骤:T 段出口跑一次全套闸(按域选档,本批只碰 `game/`),期望全绿(含 S13 基线零新增)+11 号闸 NEED-APPROVAL 留痕(触 face=data/tables+damage_controller,§0)。 ### T2 呈现域缺陷修+断言(≈1–1.25d) -- [ ] 实装 d2(`_intent_charge` 分档)+d3(ui_kit:28 注释订正)+standee_fx_sweep_test 断言①:`set_pending("damage", "heavy")` → `_intent_charge == true`;`set_pending("damage", "非蓄力id")` → false;`set_pending("buff", …)` → false。可核查结果:断言绿。 +- [ ] 实装 d2(`_intent_charge` 分档)+d3(ui_kit:28 括号引述整段删)+standee_fx_sweep_test 断言①:`set_pending("damage", "heavy")` → `_intent_charge == true`;`set_pending("damage", "非蓄力id")` → false;`set_pending("buff", …)` → false。可核查结果:断言绿。 - [ ] 实装 d4(句柄 kill)+断言②:直建 BattleEndOverlay 入树 → `open_victory(...)` 两次 → 断言任一时刻活跃 celebrate tween 至多一个(旧句柄非 running/已 kill)→ `close()` 后 `_celebrate_tw` 无效或空。可核查结果:断言绿。 -- [ ] 实装 d5/d6/d7/d8(互斥四口)+断言③:直建 DebugOverlay → `set_sim_running(true)` → `_dbg_btn.disabled == true`;TuneSimController 假 panel+假 driver(:16 `_init` 注入位)跑 `run(2)`,driver 回调内记录 `is_running()` → 断言运行中 true、收尾 false;system_test 两断言:活跃冒险中直调 `_on_tune_simulate(3)` → `_tune_sim.is_running()` 保持 false(d7 守卫早退半);`_start_debug_levels` 的模拟运行态半以 d5+d6 单元断言承载(系统路径难真实构造在跑模拟——如实注记)。可核查结果:断言绿。 -- [ ] 实装 d9(三早退)+modal_flow_test 扩展断言④:未登记层 open → 已开层 visible 全不变+该层不可见(早退证明);A/B 双层开 A(B 被隐)→ 重复 open A → close A → B 恢复可见(幂等不吞遮挡账);未登记层 close → 零副作用。可核查结果:断言绿。 -- [ ] 实装 d12(产发端增键+访问器+`_card_by_id`+`enemy_standee_center` 改签名+row_pacer 取用)+断言⑤:两 StandeeBody 同 `display_name`(如「哥布林」)异 `enemy_id` 挂 `_cards` → 按 id 各自命中;id 空时按名兜底行为同旧;damage_controller_test 扩:开单后行内 `"target_id"` == 目标敌 enemy_id;pacing_queue_test 扩:row 携 target_id 时解析调用传 id(假 stage 记参断言)。可核查结果:断言绿。 +- [ ] 实装 d5/d6/d7/d8(互斥四口)+断言③:直建 DebugOverlay → `set_sim_running(true)` → `_dbg_btn.disabled == true`;TuneSimController 假 panel+假 driver(:16 注入位)跑 `run(2)`,driver 回调内记录 `is_running()` → 断言运行中 true、收尾 false。system_test 两断言:**wd7**=真实冒险**关间态**(is_adventure=true 且 settlement==null——选路停点态,非战斗中;战斗中调用则守卫首条件已拦、断言空转)直调 `_on_tune_simulate(3)` → `_tune_sim.is_running()` 保持 false(d7 守卫早退;回退 d7 hunk 后 is_running 变 true 即红——调用后立即置回 `_tune_sim._running = false` 清理);**wd6**=闲时态白盒置态 `main._tune_sim._running = true` → 直调 `_start_debug_levels()` → 断言 `run_scope.settlement == null` 且开始层未被收起(守卫早退)→ 清理置态(回退 d6 hunk 后守卫漏模拟态即红)。可核查结果:断言绿。 +- [ ] 实装 d9(fail-fast+合并制)+modal_flow_test 扩展断言④:未登记层 open → 已开层 visible 全不变+该层不可见;A/B 双层开 A(B 被隐)→ 重复 open A → 断言 B 仍隐(V6 语义)→ close A → **B 恢复可见(合并制吞账修复)**;未登记层 close → 零副作用;:40-48 V6 在役序列原样绿。可核查结果:断言绿。 +- [ ] 实装 d12(产发端增键+standee 访问器+`_card_by_id`+`enemy_standee_center` 改签名+`:308` on_step_row_fx 解析同改+row_pacer 取用)+断言⑤:两 StandeeBody 同 `display_name`(如「哥布林」)异 `enemy_id` 挂 `_cards` → 按 id 各自命中(两口各断言一次);id 空时按名兜底行为同旧;damage_controller_test 扩:开单后行/载荷 `"target_id"` == 目标敌 enemy_id;pacing_queue_test 扩:row 携 target_id 时解析调用传 id(假 stage 记参断言)。可核查结果:断言绿。 - [ ] 实装 d17(await 后守卫)+d18(lumas_out 类型)。可核查结果:`python tools/audit_type_hints.py` 对 board_view:998 零命中。 -- [ ] 撤销证明:⑤回退 d2 → 断言①脚本错红(`_intent_charge` 未定义);⑥回退 d4 kill 段 → 断言②活跃句柄数红;⑦回退 d5 → 断言③ disabled 半红;⑧回退 d8 → 断言③ is_running 半脚本错红;⑨回退 d9 → 断言④三半红;⑩回退 d12 站桩半 → 断言⑤红;⑪d17 守卫面申报「无独立断言、撤销不适用——以全库守卫惯例一致性走查代」(如实标注不硬凑)。记录表进实现报告。 +- [ ] 撤销证明:③回退 d2 hunk → 断言①直跑输出经 error_scan 扫出 SCRIPT ERROR 红(`_intent_charge` 未定义);④回退 d4 kill 段 → 断言②活跃句柄数红;⑤回退 d5 hunk → 断言③ disabled 半红;⑥回退 d8 hunk → 断言③ is_running 半 error_scan 红;⑦回退 d9 合并段 hunk → 断言④ B 恢复半红(吞账复现);⑧回退 d12 站桩半 hunk → 断言⑤红。等价类申报:d3/d13/d17/d18 撤销不红属预期(注释/守卫惯例/类型面,如实标注——d17 以走查承载)。记录表进实现报告。 - [ ] 验收步骤:T 段出口跑一次全套闸(按域选档),期望全绿。 ### T3 渲染闸 golden 判定+产出物落位卡(≈0.5d,末卡) - [ ] golden 判定(契约 6):跑渲染闸读棋盘三图+菜单 changed 读数×4,按 README 双态判定;changed>0 落棋盘区=修对的证据,显式呈报后定重制+复闸。可核查结果:读数与判定结论进实现报告。 -- [ ] 轻闸全绿后、合并前写齐三份:`reports/iter-实现报告-<完成日>.md`(各单元状态+撤销证明记录表+golden 判定读数+实机目检总清单〔蓄力敌意图三档观感/同名敌弹道落点两条〕+遗留读数义务)/`reports/iter-代拍板追认单-<完成日>.md`(§10 白名单内代拍项留痕)/`reports/iter-反哺点-<完成日>.md`(§6 各条有落点)。可核查结果:三文件在 `reports/` 且逐条有落点。 +- [ ] 轻闸全绿后、合并前写齐三份:`reports/iter-实现报告-<完成日>.md`(各单元状态+撤销证明记录表〔含等价类申报行〕+golden 判定读数+实机目检总清单〔蓄力敌意图三档观感/同名敌受击闪白与弹道落点两条〕+遗留读数义务)/`reports/iter-代拍板追认单-<完成日>.md`(§10 白名单内代拍项留痕)/`reports/iter-反哺点-<完成日>.md`(§6 各条有落点)。可核查结果:三文件在 `reports/` 且逐条有落点。 - [ ] 合并前置:独立验收审计完成且报告 `reports/iter-验收审计-<完成日>.md` 逐行「通过」——未通过不得合并(审计入口=未参与实现的会话/子代理,只读本卡、实现报告对照表、diff 与测试件,自跑最窄抽查,不采信「已全绿」)。 **估时合计 ≈3–3.5d**(T0 0.25+T1 1–1.25+T2 1–1.25+T3 0.5)。切分预案:T1/T2 各含一次全套闸出口,超软盒时 d12(跨 core/presentation/排播三面)可独立成波。**编排注记**:本卡先行于 R1–R3 重构批落地(§0);与卡②先后皆可、d18 已替其消一件存量红;估时低于 iter-plan 四查③硬下限,与同会话他卡同批编入。 @@ -228,59 +229,59 @@ | # | 需求点 | 测什么 | 落点 | |---|---|---|---| -| V1 | 同内容双敌单据不作废(d1) | B 死亡不废 A 单据;A 死亡废 A 单据 | damage_controller_test 扩 | +| V1 | 同内容双敌单据不作废(d1,语义加固) | 夹具双敌:B 死亡不废 A 单据;A 死亡废 A 单据 | damage_controller_test 扩 | | V2 | 蓄力档可达(d2/d3) | `_intent_charge` 两态;非蓄力零置位 | standee_fx_sweep 断言① | | V3 | 庆祝 tween 不叠加(d4) | 活跃句柄至多一;close 即 kill | standee_fx_sweep 断言② | -| V4 | 批量模拟互斥闭合(d5–d8) | 调试钮随模拟置灰;控制器运行态可查;守卫早退 | standee_fx_sweep 断言③+system_test | -| V5 | 模态栈 fail-fast(d9) | 未登记层 open/close 零副作用;重复 open 不吞遮挡账 | modal_flow_test 扩 | +| V4 | 批量模拟互斥闭合(d5–d8) | 调试钮随模拟置灰;控制器运行态可查;两守卫早退 | standee_fx_sweep 断言③+system_test | +| V5 | 模态栈 fail-fast+吞账修复(d9) | 未登记层零副作用;重复 open 不吞遮挡账;V6 在役断言同绿 | modal_flow_test 扩 | | V6 | 信号契约成文(d10) | 两契约在位;全库载体 grep 零 `#` 命中 | grep+走查 | | V7 | 数值入表(d11/d16a) | 表值==原字面量;消费端读表;现价逐位等价 | level_shop_economy_test 扩+单测 | -| V8 | 站桩按键解析(d12) | 同名异 id 各自命中;行携 target_id;排播链传 id | standee_fx_sweep 断言⑤+pacing_queue_test 扩+damage_controller_test 扩 | +| V8 | 站桩按键解析(d12,两口) | 同名异 id 两口各自命中;行携 target_id;排播链传 id | standee_fx_sweep 断言⑤+pacing_queue_test 扩+damage_controller_test 扩 | | V9 | 等价重构不破坏(d13–d18) | 公式单点同值;调用点改签名后套件绿;int() 包裹后套件绿;守卫/类型补齐 | board_generator_test+全量闸+S9 | | V10 | golden 判定 | changed 读数×4+判定结论 | 渲染闸+README 记录 | | V11 | 反哺点清单 | §6 各条有落点 | 件核对(T3 出口) | ### 8.2 改动—验收对照表 -> 断言 desc 统一尾缀〔wd#〕;撤销证明逐条对应 T1/T2 撤销步。 +> 断言 desc 统一尾缀〔wd#〕;撤销证明逐条对应 T1/T2 撤销步;**证明纪律=2026-10-24 P0 令(只回退本批 hunk,禁注入造红)**。 | 需求点 | 改动 | 验收测试(尾缀) | 层级 | 真实入口 | 撤销证明 | |---|---|---|---|---|---| -| wd1 双敌单据 | `damage_controller.gd:215` 判定符 | 同内容双敌两断言〔wd1〕damage_controller_test 扩 | 单元 | 控制器真实构造(ConfigDB/RngService/UnitContainer 全链,F20 先例)+`unit_died.emit` 真实事件 | 回退 d1 → 红(T1①) | -| wd2 蓄力档 | `standee_body.gd:171-194` 布尔分档 | 断言①〔wd2〕standee_fx_sweep_test | 单元 | `set_pending` 真实调用链(快照投影 pid) | 回退 d2 → 脚本错红(T2⑤) | +| wd1 双敌单据(语义加固) | `damage_controller.gd:215` 判定符 | 夹具双敌两断言〔wd1〕damage_controller_test 扩 | 单元 | 控制器真实构造(ConfigDB/RngService/UnitContainer 全链,F20 先例)+`unit_died.emit` 真实事件;夹具=生产不可达语义面的显式钉住(F1 定性如实注记) | 回退 d1 hunk → 夹具断言红(T1①)——生产盘面撤销不红属预期,如实申报 | +| wd2 蓄力档 | `standee_body.gd:171-194` 布尔分档 | 断言①〔wd2〕standee_fx_sweep_test | 单元 | `set_pending` 真实调用链(快照投影 pid) | 回退 d2 → error_scan 红(T2③) | | wd3 注释订正 | `ui_kit.gd:28` | 走查(注释面) | — | — | 不适用(随 wd2 复核) | -| wd4 庆祝句柄 | `battle_end_overlay.gd:281-287/156-161` | 断言②〔wd4〕standee_fx_sweep_test | 单元 | `open_victory`/`close` 真实开合链 | 回退 kill 段 → 红(T2⑥) | -| wd5 调试钮 | `debug_overlay.gd:84` | 断言③ disabled 半〔wd5〕 | 单元 | `set_sim_running` 真实信号路径 | 回退 d5 → 红(T2⑦) | -| wd6 调试开局守卫 | `main.gd:712-717` | system_test+断言③〔wd6〕 | 系统+单元 | 真实冒险态直调守卫入口(信号处理器本体);模拟态半=单元承载(T2 注记) | 回退 d6 → 红(T2⑦同族) | -| wd7 模拟守卫 | `main.gd:1489` | system_test〔wd7〕 | 系统 | 真实冒险中直调 `_on_tune_simulate` | 回退 d7 → 红 | -| wd8 运行态面 | `tune_sim_controller.gd` | 断言③ is_running 半〔wd8〕 | 单元 | `run()` 真实执行体+driver 注入位 | 回退 d8 → 脚本错红(T2⑧) | -| wd9 模态 fail-fast | `modal_stack.gd:21-38` | 断言④三半〔wd9〕modal_flow_test 扩 | 单元 | ModalStack 直构+哑 Control(宿主先例) | 回退 d9 → 红(T2⑨) | -| wd10 信号契约 | `minesweeper_rules.gd:8-9`+28 行 | grep 零命中+契约走查〔wd10〕 | 静态扫描+走查 | 发射位实查(:129/:303/:310/:345/:476) | 回退 d10 → grep 红(T1④) | -| wd11 数值入表 | shop/hero 表+config_db+level_runner/unit_container | 表读断言+等价断言〔wd11〕level_shop_economy_test 扩+单测 | 单元 | ConfigDB 真装载+pool_price/英雄构造真实消费链 | 改 .tres 值 → 表读断言红(T1②) | -| wd12 按 id 解析 | `damage_controller:168/370/400/504`+`standee_body`+`battle_stage_view`+`row_pacer` | 断言⑤+产发断言+排播断言〔wd12〕三宿主 | 单元 | 站桩装载链(set_data enemy_id)+排播真实行驱动 | 回退站桩半 → 断言⑤红(T2⑩) | -| wd13 孤儿注释 | `treasure_items.gd:55-62` | 走查(注释面静态半) | — | — | 不适用(非行为改动) | -| wd14 公式单点 | `board_generator.gd:97/334/281` | 同值断言+套件绿〔wd14〕board_generator_test | 单元 | 生成期/断言期两真实调用点 | 等价重构申报:同值断言为判据,撤销不红属预期(T1 记录表如实记) | -| wd15 常量化 | `action_economy.gd:191-192` | 全量闸回归线〔wd15〕 | 集成 | finish_round_stop 真实结算链(既有套件覆盖) | 同 wd14 性质(等价重构申报) | -| wd16 英雄名/Variant | `unit_container:55/257/270`+`status_container` 四处+hero 表 | 表读断言+套件绿〔wd16〕 | 单元 | spawn/apply_damage/heal/apply_effect/decay 真实链(既有套件覆盖) | 回退 d16a 读表 hunk → 取值断言红(T1③) | -| wd17 await 守卫 | `settlement_fx_view.gd:94-95` | 走查+惯例一致性〔wd17〕(申报:无独立断言) | 走查 | play_damage_number 真实演出链 | 申报豁免(T2⑪如实标注) | +| wd4 庆祝句柄 | `battle_end_overlay.gd:281-287/156-161` | 断言②〔wd4〕standee_fx_sweep_test | 单元 | `open_victory`/`close` 真实开合链 | 回退 kill 段 → 红(T2④) | +| wd5 调试钮 | `debug_overlay.gd:84` | 断言③ disabled 半〔wd5〕 | 单元 | `set_sim_running` 真实信号路径 | 回退 d5 → 红(T2⑤) | +| wd6 调试开局守卫 | `main.gd:712-717` | system_test 白盒置态断言〔wd6〕 | 系统 | 守卫入口直调+真实闲时态(`_tune_sim._running` 白盒置态即真实运行态位面) | 回退 d6 → 守卫漏模拟态 → settlement 非 null 红(T2②wd6) | +| wd7 模拟守卫 | `main.gd:1489` | system_test〔wd7〕 | 系统 | 真实冒险关间态(is_adventure 且 settlement==null)直调 `_on_tune_simulate` | 回退 d7 → is_running 变 true 红(T2②wd7) | +| wd8 运行态面 | `tune_sim_controller.gd` | 断言③ is_running 半〔wd8〕 | 单元 | `run()` 真实执行体+driver 注入位 | 回退 d8 → error_scan 红(T2⑥) | +| wd9 模态 fail-fast+合并制 | `modal_stack.gd:21-38` | 断言④四半〔wd9〕modal_flow_test 扩+:40-48 V6 同绿 | 单元 | ModalStack 直构+哑 Control(宿主先例) | 回退合并段 → B 恢复半红(T2⑦) | +| wd10 信号契约 | `minesweeper_rules.gd:8-9`+28 行 | grep 零命中+契约走查〔wd10〕 | 静态扫描+走查 | 发射位实查(:129/:303/:310/:345/:476) | 回退 d10 契约 → grep 红(T1②) | +| wd11 数值入表 | shop/hero 表+config_db+level_runner/unit_container | 表读断言+等价断言〔wd11〕level_shop_economy_test 扩+单测 | 单元 | ConfigDB 真装载+pool_price/英雄构造真实消费链 | 等价类申报:撤销不红属预期(原值迁移)——等价断言+读数对拍承载 | +| wd12 按 id 解析(两口) | `damage_controller:168/370/400/504`+`standee_body`+`battle_stage_view:308/:342`+`row_pacer` | 断言⑤(两口)+产发断言+排播断言〔wd12〕三宿主 | 单元 | 站桩装载链(set_data enemy_id)+fx/排播真实行驱动 | 回退站桩半 → 断言⑤红(T2⑧) | +| wd13 孤儿注释 | `treasure_items.gd:55-62` | 走查(注释面) | — | — | 不适用(非行为改动) | +| wd14 公式单点 | `board_generator.gd:97/334/281` | 同值断言+套件绿〔wd14〕board_generator_test | 单元 | 生成期/断言期两真实调用点 | 等价类申报:同值断言为判据,撤销不红属预期 | +| wd15 常量化 | `action_economy.gd:185/191-192` | 全量闸回归线〔wd15〕 | 集成 | finish_round_stop 真实结算链(既有套件覆盖) | 同 wd14 性质(等价申报) | +| wd16 英雄名/Variant | `unit_container:55/257/270`+`status_container` 四处+hero 表 | 表读断言+套件绿〔wd16〕 | 单元 | spawn/apply_damage/heal/apply_effect/decay 真实链(既有套件覆盖) | 等价类申报(同 wd11) | +| wd17 await 守卫 | `settlement_fx_view.gd:94-95` | 走查+惯例一致性〔wd17〕(申报:无独立断言) | 走查 | play_damage_number 真实演出链 | 申报豁免(T2 如实标注) | | wd18 参数类型 | `board_view.gd:998` | `python tools/audit_type_hints.py` 该行零命中〔wd18〕 | 静态扫描 | 三调用点真实形态(F19) | 回退类型 → S9 R3 命中红 | | wd19 产出物 | T3 三份 | 件核对〔wd19〕 | — | — | 删一落点 → 件核红 | -**测试方式两分法**:V1–V9 全机检;能力验证经真实构造/事件链驱动(调试接口零用)。**用户目检项**(登记不阻塞):蓄力敌(heavy 技能敌)意图三档观感+同名敌弹道落点两条,写进实现报告目检总清单。 +**测试方式两分法**:V1–V9 全机检;能力验证经真实构造/事件链驱动(调试接口零用)。**用户目检项**(登记不阻塞):蓄力敌(heavy 技能敌)意图三档观感+同名敌受击闪白与弹道落点两条,写进实现报告目检总清单。 -**闸口径**:轻闸每任务卡出口自跑;批末重闸=`tools/run_all_gates.sh` 按改动域选档(本批只碰 `game/`)全绿才合并+改前改后读数对拍;11 号闸触面 NEED-APPROVAL 留痕不判红(§0)。回归措辞:里程碑步出口一次全套;波内修复只做最窄确认;新增测试先行孤立验证再并入。 +**闸口径**:轻闸每任务卡出口自跑;批末重闸=`tools/run_all_gates.sh` 按改动域选档(本批只碰 `game/`;域划分唯一出处=脚本头注)全绿才合并+改前改后读数对拍;11 号闸触面 NEED-APPROVAL 留痕不判红(§0);S13 gdstyle 基线零新增(§0)。回归措辞:里程碑步出口一次全套;波内修复只做最窄确认;新增测试先行孤立验证再并入。 ### 8.3 测试削弱申报(test-conventions §9.5) -零削弱;唯一既有测试改动=board_gen_reward_test:145/board_generator_test 的 `legality` 调用签名随 d14 同批改(签名变更非削弱,申报在案);既有断言零删除零放宽。 +零削弱;唯一既有测试改动=board_gen_reward_test:145/board_generator_test 的 `legality` 调用签名随 d14 同批改(签名变更非削弱,申报在案);既有断言零删除零放宽——**modal_flow_test :40-48 V6 序列原样保留且必须同绿(契约 5)**。 **独立验收审计(test-conventions §9.7)**:合并前由未参与实现的会话/子代理审计——只读本卡、实现报告对照表、diff 与测试件,自跑最窄抽查;报告落 `reports/iter-验收审计-<完成日>.md`,未通过不得合并。 ## 9. 异常分级 -- **L1(自救)**:`target_mine_count`/`_card_by_id`/`standee_fx_sweep_test` 命名与签名细节(接口块签名语义不变前提);d10 契约措辞(三要素不变);d3 注释保留面微调(两引用址实况跟随);断言夹具构造细节。 -- **L2(记录继续)**:orchestrator:718 treasure_used 行 target 形态扩入 d12 产发端清单;pacing_queue_test 夹具与假 stage 形态适配;跨表校验器新字段登记与否;wd14/wd15 等价重构单元的断言挂点微调。 -- **L3(停机呈报)**:同内容双敌夹具构造不出(池状态/技能行复制面受阻);golden 判失效且重制面涉及非本批像素;发现钉值表现状与 §3 不符(含 28 处清单漂移);任一既有套件出非本批存量红;d11/d16a 等价断言不成立(表迁移后现价/构造逐位不一致——数值面意外变化);任何要求顺带改数值/编排逻辑/⑦头注的诉求。 +- **L1(自救)**:`target_mine_count`/`_card_by_id`/`standee_fx_sweep_test` 命名与签名细节(接口块签名语义不变前提);d10 契约措辞(三要素不变);断言夹具构造细节。 +- **L2(记录继续)**:d9 合并制残边注记——上层「其间被重新 open 又被显式 close」的 stale 遮挡记录会在 close 下层时复活,现调用面与 V6 流不触及、接受为域外(第二轮复核注记在案);orchestrator:718 treasure_used 行 target 形态扩入 d12 产发端清单;:168/:400 fx 载荷键下发面核类结果;pacing_queue_test 夹具与假 stage 形态适配;跨表校验器新字段登记与否;wd6 白盒置态的清理写法。 +- **L3(停机呈报)**:夹具双敌字典构造不出(单位键集复刻受阻);golden 判失效且重制面涉及非本批像素;发现钉值表现状与 §3 不符(含 28 处清单漂移);任一既有套件出非本批存量红;d11/d16a 等价断言不成立(表迁移后现价/构造逐位不一致——数值面意外变化);modal_flow_test V6 序列与 d9 修法无法同绿(合并制失效——回呈修法裁决);任何要求顺带改数值/编排逻辑/⑦头注的诉求。 ## 10. 代拍板白名单(超清单必呈报) @@ -294,7 +295,8 @@ **零待裁点,开工门=U0。** -四处灰色地带已按设计事实推导定值(用户可否决,随 T3 反哺点清单逐条列示呈报): +五处灰色地带已按设计事实推导定值(用户可否决,随 T3 反哺点清单逐条列示呈报): +- **d1 定性为语义加固而非行为修复**——依据=handle_id 生产不可达实证(F1)+iter36 P0 纪律下「生产盘面撤销不红」须如实申报;备选「按审计原述定性为行为缺陷」淘汰依据=审计前提读数被 unit_container:98 排除(本卡 §3 已订正回呈)。 - **d12 用 enemy_id 增键而非槽位 index**——依据=单位字典自带 enemy_id(F12)零新造键语义、槽位随编排重排会漂;备选「槽位 index」淘汰依据=时序耦合。 - **d11 走标量 knob 不扩 SHELF_KINDS 词表**——依据=relic 是池令牌非货架种(F11 注释自证)、扩词表属数值批设计裁;备选「pool_shelf 增 relic 行」淘汰依据=词表封闭性+现价公式 relic 专枝已存在(:894)。 - **d15 蓄力上限走模块常量不入表**——依据=机制结构常量先例(STANDEE_FOOT_MARGIN 同型);备选「入 action_economy.tres」淘汰依据=审计未判其为玩法数值、无调参诉求。 @@ -302,6 +304,8 @@ ## 12. 自审六查与 grilling 复核记录 -**自审六查(2026-10-24 写卡会话)**:①规格覆盖——19 单元逐条挂 T1/T2/T3 并指到 wd1–wd19;②步骤扫描——一步一动作一可核查结果,零函数体;③类型一致性——接口块签名与 F1–F19 实查逐字一致;④审查焦点+改动覆盖——补挂:同内容双敌(wd1 正反两断言)、兜底路径语义(wd12 三宿主)、等价断言(wd11)、golden 修对证据面(契约 6)、d17 无断言如实申报(T2⑪);⑤篇幅比例——钉值表与 T 卡≈1:1,零代码块;⑥落位与复用——唯一新增文件 standee_fx_sweep_test 的域归属与既有宿主分工已答(预检节),两表三字段各归其主。 +**自审六查(2026-10-24 写卡会话)**:①规格覆盖——19 单元逐条挂 T1/T2/T3 并指到 wd1–wd19;②步骤扫描——一步一动作一可核查结果,零函数体;③类型一致性——接口块签名与 F1–F19 实查逐字一致(v1.1 补全返回类型与参数类型);④审查焦点+改动覆盖——补挂:同内容双敌(wd1 正反两断言+定性申报)、两口解析(wd12 两半)、等价断言(wd11/wd14/wd16)、golden 修对证据面(契约 6)、d17 无断言如实申报;⑤篇幅比例——钉值表与 T 卡≈1:1,零代码块;⑥落位与复用——唯一新增文件 standee_fx_sweep_test 的域归属与既有宿主分工已答(预检节),两表三字段各归其主。 -**grilling 复核记录**:v1.0 成文后独立子代理对抗复核——记录见本节(复核后补写)。 +**grilling 第一轮复核记录(2026-10-25,独立子代理对抗复核)**:判回炉三阻断——A-1 d1 缺陷前提生产不可达(unit_container:98 handle_id——验收链「真实构造+撤销」自相矛盾);A-2 d9 幂等直返与 modal_flow_test :40-48 V6 在役断言冲突;A-3 d12 漏 `battle_stage_view.gd:308` on_step_row_fx 第二解析口(审计「闪白/击杀」半不修)。随同九应修(A-4 iter36 已入库陈述过时+第三卡漏记;A-5 接口块两处缺类型;A-6 改 .tres 值造红违 P0 令;A-7 脚本错红判出口径缺 error_scan;A-8 wd6 无断言支撑;A-9 d3 两引用址实为失真;A-10 grep 命令 -P 订正;A-11 fx 载荷与行的措辞;A-12 d15 注释随动)+两建议。v1.1 全部折入:d1 重定性(语义加固+夹具断言+生产盘面撤销申报)、d9 改合并制(V6 同绿硬约束入契约 5)、d12 扩两口、§0 换代(iter36 入库/S13 gdstyle/P0 令出处)、接口块全类型、撤销步全改「只回退本批 hunk」形态、wd6/wd7 补真断言、F1/F3/F9/F10/F12/F20 六条事实按 grilling 补查订正。复核结论:三阻断闭合、九应修落位(v1.1)。 + +**grilling 第二轮复核记录(2026-10-25,同代理续核)**:总判**通过**——d1 重定性自洽(夹具钉语义+生产盘面撤销申报三件自洽)、d9 合并制经 modal_flow_test :40-60 全序列推演与 V6 同绿、d12 两口齐、九应修全折入。拟议的「d9 push_error 是否误触 error_scan」经在库反证消解(config_db_fatal_oob_test 成功路径必经 push_error 而长期绿——本引擎 push_error 输出不含 SCRIPT ERROR 标记,非问题)。余四条建议级:分类口径统一(完成定义 2 d17 单列)、wd7 时点钉死关间态、d9 残边注记(L2)、wa8→u7–u9 与应修计数订正——v1.2 已全部折入。零阻断零应修,卡进可编排态。 diff --git a/reports/需求卡片-重构boardview拆件批-2026-10-24.md b/reports/需求卡片-重构boardview拆件批-2026-10-24.md index f7016a44..3ebfb978 100644 --- a/reports/需求卡片-重构boardview拆件批-2026-10-24.md +++ b/reports/需求卡片-重构boardview拆件批-2026-10-24.md @@ -1,67 +1,70 @@ -# 需求卡片:重构 boardview 拆件批(瓦片静态算法族 TilePalette+英雄精灵状态机族拆出) +# 需求卡片:重构 boardview 拆件批(瓦片件 TilePalette+英雄精灵件 HeroSprite 拆出) -- 版本:**v1.0**(2026-10-24 成文;grilling 复核记录见 §12) -- 来源:[待办清单](../待办清单.md)「game 代码结构审查批——行为缺陷定点修+结构重构候选」条目之结构重构候选(2026-10-24 用户裁**五件全部立项**,本卡为 board_view 拆件件)(唯一事实源:工程直入证据指认=审计报告 [reports/审计-game代码结构审查-2026-10-24.md](审计-game代码结构审查-2026-10-24.md) §三 大文件表 board_view 行+本写卡会话结构实查〔本卡 §3〕) -- 归属:`game/presentation/views/board_view.gd`(拆出源)+ `game/presentation/views/tile_palette.gd`(**新增**·瓦片静态算法装配器)+ `game/presentation/views/hero_sprite.gd`(**新增**·英雄精灵状态机件)+ 调用点改引(board_view 内部+tests/probe 外部直引) -- 排期:未编入(迭代批卡片;估时 ≈1–1.5 工作日);**前置=卡①先行落地**(其 d18 触点 :998 在瓦片族内);与 R1/R3 零文件交叠 +- 版本:**v1.2**(2026-10-24 v1.0 成文→2026-10-25 grilling 第一轮修订 v1.1〔三阻断+四应修折入〕→第二轮复核「通过(附应修)」,两条应修(查表族棋盘态依赖/TILE_ 常量直读归属)折入定稿;复核结论见 §12) +- 来源:[待办清单](../待办清单.md)「game 代码结构审查批——行为缺陷定点修+结构重构候选」条目之结构重构候选(2026-10-24 用户裁**五件全部立项**,本卡为 board_view 拆件件)(唯一事实源:工程直入证据指认=审计报告 [reports/审计-game代码结构审查-2026-10-24.md](审计-game代码结构审查-2026-10-24.md) §三 大文件表 board_view 行+本写卡会话结构实查〔本卡 §3——审计「瓦片算法 ~230 行」经实查须并入查表族与缓存态方成立,§12 订正回呈〕) +- 归属:`game/presentation/views/board_view.gd`(拆出源)+ `game/presentation/views/tile_palette.gd`(**新增**·瓦片件——静态算法+装载缓存+查表一体)+ `game/presentation/views/hero_sprite.gd`(**新增**·英雄精灵件,Node2D)+ 调用点改引 +- 排期:未编入(迭代批卡片;估时 ≈1.5 工作日);**前置=卡①先行落地**(其 d18 触点 :998 在瓦片族内);与 R1/R3 零文件交叠 - 开工门:U0+grilling 复核门过(§12) ## 0. 前置依赖与并行性 - **第〇步核对(2026-10-24 写卡会话)**:来源条目设计面=工程直入、状态=待写卡;重构候选 2026-10-24 用户裁全部立项——工程直入重构类,凭审计 §三行号级证据放行。 -- **顺序硬约束**:卡①先行(d18 lumas_out 类型补齐后随族迁移,等价搬运不回退);卡② S9 注解若先行,其 board_view 位点注解随迁。 -- 与 R1(main.gd)/R3(runner)零文件交叠;棋盘 golden 基线由 `board_shot_probe`+auto_player novice 档生成(文案卡 F7 同源事实)——本批等价拆件,基线像素必须逐位不变。 +- **顺序硬约束**:卡①先行(d18 lumas_out 类型补齐后随族迁移,等价搬运不回退);卡② S9 注解若先行,board_view 位点注解随迁。R1/R3 零文件交叠可并行波。 +- **与迭代 36(已实现入库)**:文案清扫批 wa8 触点 `board_view.gd:730/:778/:782`(字形与哨兵)与 iter36 wc5 的 `ui_contrast_probe.gd:150` 直引(grilling 实查仍在原址未漂)——本批直引改引后探针调用同步改址(B2 清单),零 hunk 交叠实测成立。 +- **gdstyle S13(已落地)**:两新件落在 S13 扫描面——基线零新增。 +- 棋盘 golden 基线由 `board_shot_probe`+auto_player novice 档生成(文案卡 F7 同源事实)——本批等价拆件,基线像素必须逐位不变。 ## 1. 目标与完成定义 -**目标**:board_view.gd(1219 行,五职责混装)的「最划算两刀」落地——①瓦片静态算法族(装载/翻转/明度归一/墨族模式/对比度,~230 行无状态)拆出为 `tile_palette.gd` 静态装配器;②英雄精灵状态机族(~110 行)拆出为 `hero_sprite.gd`——board_view 回到 ~880 行以内、退回「格面渲染+输入翻译+探针面」三职责;零行为变更,棋盘 golden 三图逐像素不变。 +**目标**:board_view.gd(1219 行,五职责混装)的「最划算两刀」落地——①瓦片族(装载/翻转/明度归一/墨族模式/对比度/哈希查表,静态算法+装载缓存一体)拆出为 `tile_palette.gd`;②英雄精灵族(~103 行)拆出为 `hero_sprite.gd`(Node2D 件——`create_tween()` 为 Node 方法,硬约束)——board_view 收在 **≈880 行**(实码重算:净拆出 ≈341 行),退回「格面渲染+输入翻译+探针面」三职责;零行为变更,棋盘 golden 三图逐像素不变。 **改动单元清单**(🔴 契约 1): -| # | 拆出块(实查行界) | 去向 | 依据 | +| # | 拆出块(实查行界与净行数) | 去向 | 依据 | |---|---|---|---| -| r2-1 | 瓦片静态算法族:`_load_board_tiles`(:932)/`_request_dungeon_fallback`(:980)/`_flip_tex`(:987)/`_normalize_floor_luma`(:998)/`_srgb_lin`(:1024)/`_digit_ink_mode`(:1040)/`_contrast_y`(:1069)(约 :932-1085,~230 行,全 static 或无状态) | 新件 `tile_palette.gd`(静态装配器——`static func` 族;board_view 调用点与 tests/probe 直引点同批改引) | 审计 §三「瓦片静态算法+哈希查表(~230 行无状态,拆 TilePalette 静态装配器)」 | -| r2-2 | 英雄精灵状态机族:`_update_hero`(:387)/`_place_hero`(:410)/`_hero_frame_flash`(:434)/`notify_hero_move`(:451)/`play_hero_dig_bounce`(:457)/`_hero_feet`(:480)/`hero_hand_point`(:487)/`hero_sprite_scale`(:493)(:387-497,~110 行) | 新件 `hero_sprite.gd`(精灵件——持有英雄精灵节点与三态换装/位移/弹跳;board_view 经成员持用) | 审计 §三「英雄精灵状态机(~110 行)」 | -| r2-3 | 调用点改引:board_view 内部+外部直引(`terrain_tile_sets_test.gd:135`、`ui_contrast_probe.gd:150` 对 `_normalize_floor_luma` 的直引已实查在案;全集 T0 清单化) | 逐点改引 | 探针/测试缝 | +| r2-1 | 瓦片族全带:`_load_board_tiles`(:932,**持七成员装载缓存** :970-978:`_tiles`/`_floor_tiles`/`_tiles_board_type`/`_tiles_ok`/`_digit_dark_ink`/`_digit_plate`/`_seal_tex`——grilling 订正「无状态装载器」失实)/`_request_dungeon_fallback`(:980)/`_flip_tex`(:987)/`_normalize_floor_luma`(:998)/`_srgb_lin`(:1024)/`_digit_ink_mode`(:1040)/`_contrast_y`(:1069)/`_ink_y`(:1074,`_contrast_y` 唯一消费——随迁防跨件反调)/`_cell_hash`(:1081,查表族消费)+**查表族** `_is_wall`(:1089)/`_wall_tile_for`(:1098)/`_wall_center_tile`(:1136)/`_floor_tile_for`(:1155)——:932-1155 净 ≈238 行 | 新件 `tile_palette.gd`=**瓦片件**(装载缓存七成员随迁持于件内+六 static 算法+查表族经**棋盘态注入**——第二轮复核订正:`_is_wall`(:1089-1093) 读 `_board.width/height`+`_minesweeper.is_revealed(c)`、`_wall_tile_for` 四邻判定全经 `_is_wall`,件内拿不到棋盘态——查表族以件持 board/minesweeper 引用实现(rebuild 换板时随 `load_board_tiles` 同步更新),board_view 持 `tile_palette` 实例成员;v1.0「纯静态装配器」形态经 grilling 订正——装载器持缓存态,件形态定案为「持缓存装配器」) | 审计 §三「瓦片静态算法+哈希查表(~230 行)」——查表族并入方达该行数口径(§12 订正回呈) | +| r2-2 | 英雄精灵族:`_update_hero`(:387)/`_place_hero`(:410)/`_hero_frame_flash`(:434)/`notify_hero_move`(:451)/`play_hero_dig_bounce`(:457)/`_hero_feet`(:480)/`hero_hand_point`(:487)/`hero_sprite_scale`(:493)——净 ≈103 行(`cell_origin` :472-479 留驻) | 新件 `hero_sprite.gd`=**Node2D 件**(形态定案依据:`create_tween()` 是 Node 方法,英雄族三处调用——RefCounted 无此 API;grilling 订正 v1.0 两态待定);依赖面=grilling 实测清单:`_cell`/`SEP`/`_svp_container.position` 三几何量+`_world`+三纹理+状态量+tween 句柄(`_hero_feet` 自算坐标不调 `cell_origin`——B3) | 审计 §三「英雄精灵状态机(~110 行)」 | +| r2-3 | 调用点改引:board_view 内部消费点+外部直引三处(`terrain_tile_sets_test.gd:135` `_normalize_floor_luma`+`:139` `_digit_ink_mode`——grilling 补查、`ui_contrast_probe.gd:150` `_normalize_floor_luma`) | 直引改 `TilePalette.` 前缀同形调用(断言判据零变化);board_view 内部改经件成员/类前缀 | 探针/测试缝 | **完成定义**: -1. 三单元落地,board_view.gd ≤900 行(读数进实现报告);两新件各自一职责; -2. **等价三证**齐:①逐字迁移核对表(static 族逐字搬运;hero 族搬运除接收者化外逐字一致);②全套闸绿+改前改后读数对拍;③**棋盘三图 golden 逐像素 changed==0**(瓦片归一/墨族模式/英雄渲染全在像素路径上——本卡最强等价判据)+菜单 golden 同判; -3. 两新件合规(S9/S10/S11 头注/类型/禁用词); -4. 至少一条接线变异记录;三份产出物写齐(T3)。 +1. 三单元落地;**行数读数记录**(board_view 预期 ≈880、两新件各自净行数)——读数项非停机闸(拆出量以函数清单为准); +2. **等价三证**齐:①逐字迁移核对表(六 static 逐字搬运;装载器/查表/英雄族除接收者化与缓存成员随迁外逐字一致);②全套闸绿+改前改后读数对拍;③**棋盘三图 golden 逐像素 changed==0**(瓦片归一/墨族/英雄渲染全在像素路径上——本卡最强等价判据)+菜单 golden 同判; +3. 两新件合规(S9 全类型/S10 头注/S11 零禁用词/S13 基线零新增); +4. 至少一条撤销证明记录(T2);三份产出物写齐(T3)。 ## 2. 设计事实源 | # | 出处 | 取用条款 | |---|---|---| -| D1 | 工程直入证据指认=审计 §三 大文件表 board_view 行(1219 行;「至少五职责混装;最划算两刀:瓦片静态算法+哈希查表 ~230 行拆 TilePalette+英雄精灵状态机 ~110 行」)+本会话结构实查(§3) | 拆出块清单与行界 | -| D2 | [code-conventions](../design/engineering/code-conventions.md) §1 结构纪律 | 一文件一职责;ui_kit.gd 先例(§1.2 明文允许的静态装配器宿主形态——tile_palette 同型) | +| D1 | 工程直入证据指认=审计 §三 大文件表 board_view 行(1219 行;「最划算两刀」指认)+本会话结构实查(§3——查表族与缓存态归属经 grilling 订正,~230 行口径以并入查表族成立) | 拆出块清单与行界 | +| D2 | [code-conventions](../design/engineering/code-conventions.md) §1 结构纪律 | 一文件一职责;迁移禁顺手改写 | | D3 | [architecture](../design/engineering/architecture/architecture.md) 呈现层 D1 行 | BoardView=Control 壳+SubViewport+Node2D 世界的探针契约面不变 | +| D4 | 2026-10-24 用户 P0 令 | 行为验收只走撤销证明,禁注入造红 | -## 3. 现状事实(2026-10-24 写卡会话主区实查;开工日 T0 复核行号) +## 3. 现状事实(2026-10-24 写卡会话实查+2026-10-25 grilling 实测;开工日 T0 复核行号) | # | 事实 | 出处 | |---|---|---| -| B1 | board_view.gd 1219 行;瓦片族七函数 :932-1085 连续带(六 static+`_load_board_tiles` 实例无状态装载器+`_request_dungeon_fallback`);英雄族八函数 :387-497 连续带 | `game/presentation/views/board_view.gd` 结构图谱 | -| B2 | `_normalize_floor_luma` 外部直引两处:`terrain_tile_sets_test.gd:135`(`BoardViewScript._normalize_floor_luma(tex, 0.10, lumas)`)+`ui_contrast_probe.gd:150`(`BoardView._normalize_floor_luma(tex, 0.10, null)`);`_flip_tex`/`_digit_ink_mode`/`_contrast_y` 直引面 T0 清单化 | 上列 file:line | -| B3 | 英雄族依赖面:英雄精灵节点持有/换装(HeroState 枚举迁移与否 T0 定)、`cell_origin`/棋盘几何(:472-493 与几何函数互调)——拆出件需注入几何 Callable 或持有引用(最小参数化);卡① d2 触点 standee 与本族无关 | `game/presentation/views/board_view.gd:387-497` | -| B4 | 瓦片族消费链:`_load_board_tiles`←`rebuild`(:258)/`set_desaturated` 等;`_digit_ink_mode`←`_paint_cell`(:708) 墨族模式;全部在棋盘像素路径上——golden 三图为等价判据的依据 | `game/presentation/views/board_view.gd:258/708/932-1085` | -| B5 | 卡① d18 触点 `lumas_out`(:998) 在瓦片族内(前置落地后随族迁移);卡① d2/d12 触点在 standee/stage/row_pacer,零交叠 | §0;卡① §1 d18 | +| B1 | board_view.gd 1219 行;瓦片族全带 :932-1155(六 static+装载器+fallback+`_ink_y`+`_cell_hash`+查表四函数);**装载器持七成员缓存** :970-978(`_tiles`/`_floor_tiles`/`_tiles_board_type`/`_tiles_ok`/`_digit_dark_ink`/`_digit_plate`/`_seal_tex`)——「实例无状态」陈述失实(grilling 订正) | `game/presentation/views/board_view.gd:932-1155` | +| B2 | 外部直引三处:`terrain_tile_sets_test.gd:135`(`BoardViewScript._normalize_floor_luma(tex, 0.10, lumas)`)+`:139`(`BoardViewScript._digit_ink_mode(lumas)`)+`ui_contrast_probe.gd:150`(`BoardView._normalize_floor_luma(tex, 0.10, null)`——iter36 wc5 后仍在原址);其余函数直引面 T0 复扫 | 上列 file:line | +| B3 | 英雄族依赖面(grilling 实测):`_hero_feet`(:480) 自算 `Vector2(c)*(_cell+SEP)` **不调 cell_origin**;实际耦合=`_cell`/`SEP`/`_svp_container.position`(`hero_hand_point` :487 读)三几何量+`_world`+三纹理+状态量+三 tween 句柄;**board_view 无 HeroState 枚举**(全文件 grep 零命中——英雄态=纹理切换+布尔+tween 句柄,v1.0「HeroState 迁移与否 T0 定」悬空点撤销) | `game/presentation/views/board_view.gd:387-497` | +| B4 | 瓦片族消费链:`_load_board_tiles`←`rebuild`(:258)/`set_desaturated`;`_digit_ink_mode`←`_paint_cell`(:708) 墨族模式;查表族←`_paint_cell` 装配路径(:1145/:1156 消费 `_cell_hash`)——全部在棋盘像素路径上(golden 铁证依据)。**查表族棋盘态依赖(第二轮复核)**:`_is_wall` 读 `_board` 尺寸+`_minesweeper.is_revealed`——件需棋盘引用注入且随换板更新;**TILE_ 常量族**(`TILE_WALL_NAMES`/`TILE_FLOOR_VARIANTS`/`TILE_FLOOR_FMT`,装载器 :936-937 注释自证被测试直读)外部直读五处:`terrain_tile_sets_test.gd:44/45/125`、`ui_contrast_probe.gd:146/147`——常量随件迁(瓦片域唯一宿主),五处直读同批改引 | `game/presentation/views/board_view.gd:258/708/932-1155`;`game/tests/unit/presentation/terrain_tile_sets_test.gd:44/45/125`;`game/probe/ui_contrast_probe.gd:146/147` | `game/presentation/views/board_view.gd:258/708/932-1155` | +| B5 | 卡① d18 触点 `lumas_out`(:998) 在瓦片族内(前置落地后随族迁移);卡① d2/d12 触点在 standee/stage/row_pacer 零交叠;iter36 wa8 触点 :730/:778/:782 在两族带外 | 卡① §1;§0 | ## 4. 设计契约(红线,违反 = L3 停机呈报) -🔴 **契约 1 · 零行为变更**:static 族**逐字搬运**(签名含默认参逐字一致,仅类宿主变);英雄族搬运除接收者化(self→hero_sprite 件)与最小参数化外逐字一致;禁顺手改算法、禁改默认参值、禁合并/删函数。 +🔴 **契约 1 · 零行为变更**:六 static **逐字搬运**(签名含默认参逐字一致,仅类宿主变);装载器/查表/英雄族搬运除接收者化(self→件)与缓存成员随迁外逐字一致;禁顺手改算法、禁改默认参值、禁合并/删函数;装载缓存语义不变(同板型复用/换板重载时序零变化)。 -🔴 **契约 2 · golden 逐像素铁证**:棋盘三图+菜单 golden changed==0;任何非 0 即 L3(瓦片族在像素路径上,非 0=等价性破)。 +🔴 **契约 2 · golden 逐像素铁证**:棋盘三图+菜单 golden changed==0;任何非 0 即 L3(瓦片族与英雄渲染在像素路径上,非 0=等价性破)。 -🔴 **契约 3 · 探针/测试缝**:探针对 BoardView 的公开面与快照断言零变化;B2 外部直引同批改引(`BoardViewScript._normalize_floor_luma`→`TilePalette._normalize_floor_luma` 同形)且改引后套件绿;`_cards` 等探针读面不动(那是 stage 的面——board_view 探针面 T0 清单核对)。 +🔴 **契约 3 · 探针/测试缝**:探针对 BoardView 的公开面与快照断言零变化;B2 三处直引同批改引(`BoardViewScript._normalize_floor_luma`→`TilePalette.normalize_floor_luma` 同形)且改引后套件绿、断言判据零变化。 -🔴 **契约 4 · 新件合规与形态**:`tile_palette.gd`=纯静态装配器(零成员态,ui_kit 同型);`hero_sprite.gd`=精灵状态机件(节点持有+状态换装);两件头注 S10 形制+S9 全类型+S11 零禁用词。 +🔴 **契约 4 · 新件形态定案**:`tile_palette.gd`=**持缓存装配器**(七成员装载缓存+查表读缓存+六 static 算法一体;「纯静态零成员」形态经 grilling 否决);`hero_sprite.gd`=Node2D 件(`create_tween` 硬约束);两件头注 S10 形制+S9 全类型+S11 零禁用词+S13 基线零新增。 ## 5. 范围边界 -**做**:r2-1~r2-3+等价三证+接线变异+产出物。 +**做**:r2-1~r2-3+等价三证+撤销证明+产出物。 **不做**:board_view 其余三职责(格面渲染/输入翻译/探针面)的再拆分;瓦片算法本身的重写/优化(明度归一带与 Bible 冻结值不动);§三「其余小件」中 level_map_screen 事项;R1/R3 面。 @@ -70,7 +73,7 @@ | 文档 | 关联点 | 同步义务 | |---|---|---| | [architecture](../design/engineering/architecture/architecture.md) 呈现层 D1 行/装配节 | 两新拆件登记(views 层件清单变化) | 反哺点 · 列清单(①) | -| [HUD框架](../design/gdd/systems/表现与支撑/HUD框架.md)(若逐件登记 views 清单) | 新件两行(T0 核该文档是否列件清单) | 反哺点 · 列清单(②) | +| [HUD框架](../design/gdd/systems/表现与支撑/HUD框架.md)(若逐件登记 views 清单) | 新件两行(T0 核是否列件清单) | 反哺点 · 列清单(②) | | `待办清单.md`/`roadmap.md` | 条目拆分注记与迭代行编入笔 | 反哺点 · 列清单(③④) | | `game/tests/`、`game/probe/` 引用点 | 实施本体 | 实施本体(可写) | @@ -80,71 +83,73 @@ | 文件 | 职责 | 行为改动 | |---|---|---| -| `game/presentation/views/board_view.gd` | 两族拆出+调用点改引(复用既有·修改) | 非行为改动(等价迁移)→ wr1 | -| `game/presentation/views/tile_palette.gd` | **新增**:瓦片静态算法装配器(新增·新文件) | 非行为改动 → wr1 | -| `game/presentation/views/hero_sprite.gd` | **新增**:英雄精灵状态机件(新增·新文件) | 非行为改动 → wr1 | -| tests/probe 直引点 | 改引(复用既有·修改) | 非行为改动 → wr1 | +| `game/presentation/views/board_view.gd` | 两族拆出+件成员持用+调用点改引(复用既有·修改) | 非行为改动(等价迁移)→ wr1 | +| `game/presentation/views/tile_palette.gd` | **新增**:瓦片件(装载缓存+查表+六 static)(新增·新文件) | 非行为改动 → wr1 | +| `game/presentation/views/hero_sprite.gd` | **新增**:英雄精灵件 Node2D(新增·新文件) | 非行为改动 → wr1 | +| tests/probe 直引三处 | 改引(复用既有·修改) | 非行为改动 → wr1 | ### 接口块 -- `tile_palette.gd`:`extends RefCounted`+`static func` 族——`load_board_tiles(board_type: String)`(原实例无状态装载器静态化——若持缓存则保留实例形态,T0 定;命名 L1)、`flip_tex`/`normalize_floor_luma`/`srgb_lin`/`digit_ink_mode`/`contrast_y`/`request_dungeon_fallback`(签名与现 static 形逐字一致,去下划线前缀与否 L1)。 -- `hero_sprite.gd`:`extends RefCounted`(或 Node2D——随精灵节点归属,T0 定形态);持英雄精灵与三态;`update_hero/place_hero/frame_flash/notify_move/play_dig_bounce/feet/hand_point/sprite_scale`(原签名同形、接收者化)。 -- 最窄闸:`terrain_tile_sets_test` 单件直跑;探针 `probe_gate.sh` 段单跑;渲染 `render_gate.sh`(golden 判据主战场)。 +- `tile_palette.gd`:`extends RefCounted`;件内七成员装载缓存(随迁原名);`load_board_tiles(board_type: String)`(装载器——缓存语义不变;rebuild 换板时同步更新件内 board/minesweeper 引用)+查表四函数(读件内缓存+**件持棋盘引用**——`_is_wall` 依赖面,签名同形去下划线 L1)+件内 `const TILE_WALL_NAMES/TILE_FLOOR_VARIANTS/TILE_FLOOR_FMT`(常量随迁——瓦片词表唯一宿主,五处外部直读改引)+六 static(`flip_tex`/`normalize_floor_luma`/`srgb_lin`/`digit_ink_mode`/`contrast_y`/`ink_y`——签名含默认参逐字一致);board_view 持 `var _palette` 实例成员。 +- `hero_sprite.gd`:`extends Node2D`(定案——`create_tween()` Node 硬约束);持英雄精灵与状态;`update_hero/place_hero/frame_flash/notify_move/play_dig_bounce/feet/hand_point/sprite_scale`(原签名同形、接收者化;几何三量经构造注入)。 +- 最窄闸:`terrain_tile_sets_test` 单件直跑+`tools/error_scan.py` 判红口径;探针 `probe_gate.sh` 段单跑;渲染 `render_gate.sh`(golden 判据主战场)。 ### 落位与可复用性预检 -- **`tile_palette.gd`**——复用面:为什么不并入 ui_kit(既有静态装配器宿主):ui_kit 是**全 UI 共用**色彩/字体/控件装配器(§1.2 豁免的单一宿主),瓦片算法是棋盘域私有(明度归一/墨族模式只服务棋盘像素)——并入=跨域混装扩大既有 848 行件;为什么留在 board_view 不可:五职责混装即本批拆因。唯一面:瓦片装载与明度算法唯一宿主(B4 单源)。分层:presentation 层静态件零依赖(纯 Image/Texture 计算)。 -- **`hero_sprite.gd`**——复用面:全库无第二英雄精灵实现(standee 是敌/主角站桩、非棋盘小人);与 StandeeBody 为什么不合:站桩=B 区世界精灵(Node2D 绘制)vs 棋盘小人=D 区格面精灵(位移/闪帧/挖掘弹跳状态机)——域与形态都不同。唯一面:英雄小人状态机唯一宿主。分层:views 层件,几何依赖经注入。 +- **`tile_palette.gd`**——复用面:为什么不并入 ui_kit(既有 848 行静态宿主):ui_kit 是全 UI 共用色彩/字体/控件装配器,瓦片算法+装载缓存+查表是棋盘域私有——并入=跨域混装再增重;为什么留在 board_view 不可:五职责混装即本批拆因。唯一面:瓦片装载/明度算法/查表唯一宿主(B4 单源)。分层:presentation 层件零新依赖(纯 Image/Texture 计算+自有缓存)。 +- **`hero_sprite.gd`**——复用面:全库无第二英雄小人实现(standee=B 区站桩世界精灵,域与形态都不同);为什么 Node2D:`create_tween` 硬约束(B3)。唯一面:英雄小人状态机唯一宿主。分层:views 层件,几何依赖经注入。 - **零新增算法**:全部为既有函数搬运。 ### T0 事实坐实(≈0.25d) -- [ ] 复核 B1-B5+外部直引全集(grep tests/probe/sim 对七瓦片函数与八英雄函数名)+`_load_board_tiles` 缓存态与 HeroState 枚举归属判定(接口块两 T0 点)。可核查结果:直引清单+两判定结论进实现报告素材。 +- [ ] 复核 B1-B5+外部直引复扫(grep tests/probe/sim 对瓦片全带**与英雄族八函数名与 TILE_ 三常量名**)+装载缓存成员与消费点对照(:970-978 七成员的读写点全列+查表族棋盘态读写点)。可核查结果:直引与缓存消费点清单进实现报告素材。 - [ ] 改前读数(行数、套件通过数、golden 基线指纹)。可核查结果:基线表在案。 -### T1 两族拆出+改引(≈0.75–1d) +### T1 两族拆出+改引(≈1d) -- [ ] 实装 r2-1(tile_palette 新件+board_view 调用点改引+B2 两直引点改引)→ r2-2(hero_sprite 新件+接收者化迁移)→ r2-3(直引全集改引)。可核查结果:board_view ≤900 行;逐字迁移核对表逐函数落位。 +- [ ] 实装 r2-1(tile_palette 新件:装载缓存随迁+查表+六 static;board_view 件成员+调用点改引+B2 三直引点改引)→ r2-2(hero_sprite 新件:接收者化迁移+几何注入)→ r2-3(直引复扫改引)。可核查结果:board_view ≈880 行读数记录;逐字迁移核对表逐函数落位。 - [ ] 验收步骤:全套闸按域选档全绿+棋盘三图与菜单 golden changed==0(契约 2——非 0 即停)。 -### T2 接线变异+产出物落位卡(≈0.25d,末卡) +### T2 撤销证明+产出物落位卡(≈0.25d,末卡) -- [ ] 接线变异一条:临时把 `_paint_cell` 的墨族模式调用错指(如断开 digit_ink_mode 接线)→ 对应渲染/单测断言红 → 还原复绿。记录进实现报告。 -- [ ] 写齐三份产出物(实现报告含逐字迁移核对表+行数与 golden 读数+实机目检总清单〔棋盘渲染抽查:三关瓦片明度/数字墨色/英雄移动与挖掘弹跳〕/代拍板追认单/反哺点)。 +- [ ] 撤销证明一条(P0 令形态):回退 `terrain_tile_sets_test.gd:135` 改引 hunk(回指 `BoardViewScript._normalize_floor_luma` 旧址)→ 单测直跑经 error_scan 扫出 SCRIPT ERROR 红(旧址符号已随迁移消亡)→ 精确还原复绿。记录进实现报告。 +- [ ] 写齐三份产出物(实现报告含逐字迁移核对表+行数与 golden 读数+实机目检总清单〔三关瓦片明度/数字墨色/英雄移动与挖掘弹跳抽查〕/代拍板追认单/反哺点)。 - [ ] 合并前置:独立验收审计(同卡①口径)逐行「通过」。 -**估时合计 ≈1.25–1.5d**。编排注记:前置卡①;与 R1/R3 可同迭代分波;golden 判据重(渲染闸必跑)。 +**估时合计 ≈1.5d**。编排注记:前置卡①;与 R1/R3 可同迭代分波;golden 判据重(渲染闸必跑)。 ## 8. 验证闸 ### 改动—验收对照表 -| 需求点 | 改动 | 验收测试(尾缀) | 层级 | 真实入口 | 变异/撤销证明 | +| 需求点 | 改动 | 验收测试(尾缀) | 层级 | 真实入口 | 撤销证明 | |---|---|---|---|---|---| -| wr1 两族拆出等价 | board_view 两族迁出+改引 | 全套闸绿+golden changed==0+逐字迁移核对表〔wr1〕 | 集成+渲染 | 棋盘真实渲染路径(board_shot_probe/golden)+探针 | 接线变异一条(T2);等价三证替代逐单元撤销(等价重构申报) | -| wr2 新件合规 | 两新件 | S9/S10/S11 零命中〔wr2〕 | 静态扫描 | 闸真实跑批 | 回退类型/头注 → 对应闸红 | +| wr1 两族拆出等价 | board_view 两族迁出+改引 | 全套闸绿+golden changed==0+逐字迁移核对表〔wr1〕 | 集成+渲染 | 棋盘真实渲染路径(board_shot_probe/golden)+探针 | 撤销证明一条(T2);等价三证替代逐单元撤销(等价重构申报) | +| wr2 新件合规 | 两新件 | S9/S10/S11/S13 四闸零命中〔wr2〕 | 静态扫描 | 闸真实跑批 | 回退类型/头注 → 对应闸红 | | wr3 产出物 | T2 三份 | 件核对〔wr3〕 | — | — | 缺项红 | **测试削弱申报**:零(terrain_tile_sets_test 改引仅换址,断言判据零变化)。**独立验收审计**:同卡① §8.3 口径。 ## 9. 异常分级 -- **L1(自救)**:两新件命名与去下划线取舍;`_load_board_tiles` 静态化/实例化形态;HeroState 枚举随迁或留驻。 -- **L2(记录继续)**:直引清单个别点的改引适配。 -- **L3(停机呈报)**:golden changed>0(等价性破);英雄族依赖面比 B3 判定宽(接收者化不可行——判离指认失真回呈);任一套件非本批存量红;≤900 行达不成(呈报,禁自扩范围)。 +- **L1(自救)**:两新件命名与函数名前缀取舍(签名语义不变前提);几何注入面最小化写法。 +- **L2(记录继续)**:直引清单个别点改引适配;行数读数与 ≈880 的正常偏差。 +- **L3(停机呈报)**:golden changed>0(等价性破);英雄族依赖面比 B3 清单宽(接收者化不可行——判离指认失真回呈);任一套件非本批存量红;装载缓存语义无法等价随迁(消费点比 T0 清单宽)。 ## 10. 代拍板白名单 1. 两新件命名与函数名前缀取舍(签名语义不变前提)。 -2. hero_sprite 件形态(RefCounted vs Node2D)与注入面最小化写法。 +2. hero_sprite 几何注入的具体形态。 3. 提交切分与 worktree 分支命名。 ## 11. 待裁点 -**零待裁点,开工门=U0。** 一处灰色地带推导定值:瓦片族落**独立 tile_palette**而非并入 ui_kit——依据=ui_kit 全 UI 共用宿主与棋盘私有算法的域界(预检节);备选「并入 ui_kit」淘汰依据=跨域混装+该件已 848 行再增重。用户可否决(随 T2 反哺点呈报)。 +**零待裁点,开工门=U0。** 两处灰色地带推导定值(呈报可否决,随 T2 反哺点):①瓦片族落**独立 tile_palette**而非并入 ui_kit——依据=全 UI 共用宿主与棋盘私有算法+缓存的域界;备选「并入 ui_kit」淘汰依据=跨域混装+该件已 848 行再增重。②tile_palette 定形态为**持缓存装配器**(非纯静态)——依据=装载器七成员缓存的实存(B1);备选「缓存留宿主、件纯静态」淘汰依据=缓存与查表同源、拆两处即双写。hero_sprite 的 Node2D 形态非灰色地带(API 硬约束)。 ## 12. 自审六查与 grilling 复核记录 -**自审六查(2026-10-24 写卡会话)**:①规格覆盖——r2-1~r2-3→T1、合规/变异/产出物→T2,指到 wr1–wr3;②步骤扫描——一步一动作一可核查结果;③类型一致性——接口块签名与 B1-B4 实查一致(两 T0 判定点显式标注非 TBD——判定内容已给出判定依据);④审查焦点——补挂:golden 逐像素铁证(契约 2)、B2 直引改引判据不变、`_load_board_tiles` 缓存态两态判定收口;⑤篇幅比例——零实现体;⑥落位预检——两新件不能复用既有件的理由与唯一落点已答。 +**自审六查(2026-10-24 写卡会话)**:①规格覆盖——r2-1~r2-3→T1、合规/撤销/产出物→T2,指到 wr1–wr3;②步骤扫描——一步一动作一可核查结果;③类型一致性——接口块签名与 B1-B4 实查一致(v1.1 撤销 HeroState 悬空点、形态定案);④审查焦点——golden 逐像素铁证(契约 2)、B2 三直引判据不变、缓存消费点 T0 全列义务;⑤篇幅比例——零实现体;⑥落位预检——两新件不能复用既有件的理由与唯一落点已答。 -**grilling 复核记录**:v1.0 成文后独立子代理对抗复核——记录见本节(复核后补写)。 +**grilling 第一轮复核记录(2026-10-25,独立子代理对抗复核)**:判回炉三阻断——R2-A1 行数目标与清单算术断裂(v1.0 七函数 ≈156+103 行拆出后 ≈959>900,须并查表族方达 ≈887);R2-A2 `_load_board_tiles` 实持七成员缓存(:970-978),「无状态装载器」失实且与「纯静态」契约互斥;R2-A3 T2 接线变异违 P0 令。随同四应修(F1 漏 `_ink_y`/`_cell_hash`;F2 HeroState 枚举不存在于 board_view;F3 直引三处实测+iter36 陈述;F4 hero_sprite 形态缺决定性依据〔create_tween 系 Node 方法〕)。v1.1 全部折入:查表族+`_ink_y`+`_cell_hash` 并入 r2-1(≈238 行、board_view ≈880 可达)、tile_palette 定形态持缓存装配器(契约 4 重立)、hero_sprite 定 Node2D、HeroState 悬空点撤销、B3 依赖面按 grilling 清单写实、证明改撤销形态(回退改引 hunk→error_scan 红)、iter36 关系实测陈述。复核结论:三阻断闭合、四应修落位(v1.1)。 + +**grilling 第二轮复核记录(2026-10-25,同代理续核)**:总判**通过(附应修)**——三阻断真闭合(行数账自洽 1219−341≈878、缓存态契约重立、撤销证明合规)。新发现两应修:①查表族棋盘态依赖缺列(`_is_wall` 读 board 尺寸+is_revealed——接口块「读件内缓存」覆盖不了,件需棋盘引用注入);②TILE_ 常量族外部直读五处在册未列(terrain_tile_sets_test:44/45/125+ui_contrast_probe:146/147,T0 函数名 grep 兜不住)。v1.2 折入:B4 补两依赖面、接口块补棋盘引用注入与常量随迁、r2-3 直引清单+5、T0 复扫口径加常量名。零待裁点成立,卡进可编排态。 diff --git a/reports/需求卡片-重构main判离批-2026-10-24.md b/reports/需求卡片-重构main判离批-2026-10-24.md index 879c94a4..406aaa85 100644 --- a/reports/需求卡片-重构main判离批-2026-10-24.md +++ b/reports/需求卡片-重构main判离批-2026-10-24.md @@ -1,75 +1,78 @@ # 需求卡片:重构 main 判离批(数据投影/只读解析回调/文案拼装三族出组合根) -- 版本:**v1.0**(2026-10-24 成文;grilling 复核记录见 §12) -- 来源:[待办清单](../待办清单.md)「game 代码结构审查批——行为缺陷定点修+结构重构候选」条目之结构重构候选(2026-10-24 用户裁**五件全部立项**,本卡为 main.gd 判离件)(唯一事实源:工程直入证据指认=审计报告 [reports/审计-game代码结构审查-2026-10-24.md](审计-game代码结构审查-2026-10-24.md) §三 大文件表 main.gd 行+本写卡会话结构实查〔本卡 §3〕) -- 归属:`game/presentation/main.gd`(判离源)+ `game/presentation/hud_presenter.gd`(投影/文案承接件·复用既有)+ `game/presentation/board_resolvers.gd`(**新增**·解析回调承接件)+ 探针/测试引用点同批改引 +- 版本:**v1.2**(2026-10-24 v1.0 成文→2026-10-25 grilling 第一轮修订 v1.1→第二轮复核「通过(附应修)」,5 条小刀修正折入定稿;复核结论见 §12) +- 来源:[待办清单](../待办清单.md)「game 代码结构审查批——行为缺陷定点修+结构重构候选」条目之结构重构候选(2026-10-24 用户裁**五件全部立项**,本卡为 main.gd 判离件)(唯一事实源:工程直入证据指认=审计报告 [reports/审计-game代码结构审查-2026-10-24.md](审计-game代码结构审查-2026-10-24.md) §三 大文件表 main.gd 行+本写卡会话结构实查〔本卡 §3;审计「~440 行可判离/拆后 ~1070 行」读数经实查**不成立**,本卡按实码重算——§12 订正回呈〕) +- 归属:`game/presentation/main.gd`(判离源)+ `game/presentation/hud_presenter.gd`(投影/文案承接件·复用既有)+ `game/presentation/board_resolvers.gd`(**新增**·解析回调承接件) - 排期:未编入(迭代批卡片;估时 ≈1–1.5 工作日);**前置=卡①(game 行为缺陷定点修批)先行落地**(§0) - 开工门:U0+grilling 复核门过(§12) ## 0. 前置依赖与并行性 - **第〇步核对(2026-10-24 写卡会话)**:来源条目设计面=工程直入、状态=待写卡;重构候选经 2026-10-24 用户裁全部立项另立三卡(R1/R2/R3)——工程直入重构类,凭审计 §三行号级证据放行。 -- **顺序硬约束**:卡①先落地(其 d6/d7 守卫触点在本文件;缺陷修先行避免行号漂移与验收互扰);卡②(S9 注解批)若先行,其 main.gd:565 位点的注解随判离迁移(等价搬运不回退)。 -- 与 R2(board_view 拆件)/R3(runner 拆件)零文件交叠,三卡可同迭代不同波或分迭代;与迭代 36 两卡零 hunk 交叠预期(T0 复核)。 -- 探针缝约束(architecture「三屏壳与组合根句柄面」节):**探针挂载假设 `main.X` 一级句柄路径零迁移**——本卡判离的是私有函数族非句柄成员,句柄面零触碰。 +- **顺序硬约束**:卡①先落地(其 d6/d7 守卫触点在本文件 :712-717/:1486-1491);卡②(S9 注解批)若先行,其 main.gd:565 位点的注解**不随判离迁移**(:565 `build_adventure_params` 不在任何判离块——grilling 订正 v1.0 误述)。 +- **与迭代 36(已实现入库,9468c70e 等)**:iter36 卡③静态扫描归零提交含「main/_status_curios 容器参数化」——恰落在 r1-1 五函数之一的 `_status_curios` 上;**迁移基线=当前码**(iter36 已并入,无并行冲突),T0 复核现状行号。 +- 与 R2(board_view 拆件)/R3(runner 拆件)零文件交叠,可同迭代不同波或分迭代。 +- **gdstyle S13(已落地)**:新件 `board_resolvers.gd` 落在 S13 扫描面——基线零新增。 +- 探针缝约束(architecture「三屏壳与组合根句柄面」节):**探针挂载假设 `main.X` 一级句柄路径零迁移**——本卡判离的是私有函数族非句柄成员,句柄面零触碰;探针对判离函数的**五处直引**(M6)经三件薄委托保零改动(§1 r1-4)。 ## 1. 目标与完成定义 -**目标**:main.gd(1508 行,超架构文档自记 1100 行上帝对象反面线)的三族可判离块迁出组合根——①数据投影族(面板投喂字典构造)②只读解析回调族(注入 board_view 的三个 resolver+调试加成拼装)③文案拼装三件——main 回到 ≤1100 行;判离=逐字等价迁移(零行为变更),探针/测试引用点同批改引。 +**目标**:main.gd(1508 行)的三族可判离块迁出组合根——①数据投影族(五函数)②只读解析回调族(四函数)③文案拼装三件——HudPresenter 承接投影与文案、新件 board_resolvers 承接解析回调;探针直引面经薄委托零改动;判离=逐字等价迁移(零行为变更)。**行数读数(实码重算,非审计 ~440 原数)**:净判离≈140 行+三件薄委托回填≈12 行,main 收在 ≈1370–1380——审计「拆后回 ~1070」经实查不成立(其判离量读数无法复算,§12 回呈),1100 行上帝对象线的进一步下探不属本卡范围。 **改动单元清单**(🔴 契约 1): -| # | 判离块(实查行界) | 去向 | 依据 | +| # | 判离块(实查行界与净行数) | 去向 | 依据 | |---|---|---|---| -| r1-1 | 数据投影族:`_status_data`(:1076)/`_status_curios`(:1091)/`_career_data`(:1126)/`_save_select_data`(:1164)/`_camp_data`(:1238) | `hud_presenter.gd` 静态函数族(构造注入参数显式化——db/save/meta/run_scope 取值由调用侧传参) | 审计 §三「数据投影族 L1059-1205 ~135 行」+HudPresenter 既有静态投影先例(feat_holdings_lines/tune_sim_report) | -| r1-2 | 只读解析回调族:`_identity_lookup`(:762)/`_variant_mask_lookup`(:773)/`_variant_mark_lookup`(:788)+`_debug_hero_override`(:755) | 新件 `board_resolvers.gd`(构造注入 settlement/加成取值 Callable,产出三个绑定 Callable+override 拼装);main :253-256 注入点改引 | 审计 §三「只读解析回调 L755-798」;解析器自成一族、依赖面窄(settlement 只读+调试滑条) | -| r1-3 | 文案拼装三件:`_gp_summary_text`(:845)/`_bonus_summary_text`(:853)/`_phase_text`(:1393) | `hud_presenter.gd` 静态函数(纯拼装零状态) | 审计 §三「文案拼装三件」;HudPresenter 即文案拼装宿主 | -| r1-4 | 引用点改引:main 内部调用点+探针/测试外部引用点(T0 清单化) | 逐点改引新址;main 留一行接线/委托 | 探针缝纪律 | +| r1-1 | 数据投影族:`_status_data`(:1076-1090,15 行)/`_status_curios`(:1091-1098,8)/`_career_data`(:1126-1149,24)/`_save_select_data`(:1164-1177,14)/`_camp_data`(:1238-1241,4)——净 ≈65 行 | `hud_presenter.gd` 静态函数族(构造注入参数显式化——db/save/meta/run_scope 取值由调用侧传参);`_camp_data`/`_status_data`/`_status_curios` 三件在 main 留**薄委托**(探针直引零改动,r1-4) | 审计 §三「数据投影族」指认+HudPresenter 既有静态投影先例(feat_holdings_lines/tune_sim_report);行数=grilling 实测 | +| r1-2 | 只读解析回调族:`_identity_lookup`(:762)/`_variant_mask_lookup`(:773)/`_variant_mark_lookup`(:788)+`_debug_hero_override`(:755)——:755-798 净 ≈44 行 | 新件 `board_resolvers.gd`(构造注入 **db+debug_overlay+settlement 取值 Callable**——第二轮复核订正依赖面:`_identity_lookup` 三处读 `run_scope.settlement`〔:765 `minesweeper.current_board()`/:767 `presentation_snapshot()`/:769 `query_reward_identity()`〕、`_variant_*` 读 `db.variation.row_by_id`、`_debug_hero_override` 读 `db.hero`+调试滑条,无 meta);产出三个绑定解析 Callable+override 拼装;main :253-256 注入点改引 | 审计 §三「只读解析回调 L755-798」;解析器自成一族、依赖面窄 | +| r1-3 | 文案拼装三件:`_gp_summary_text`(:845-852)/`_bonus_summary_text`(:853-866)/`_phase_text`(:1393-1401)——净 ≈31 行 | `hud_presenter.gd` 静态函数(纯拼装零状态);`_gp_summary_text` 在 main 留**薄委托**(探针直引,r1-4) | 审计 §三「文案拼装三件」;HudPresenter 即文案拼装宿主 | +| r1-4 | 引用点:main 内部调用点改引+**探针直引五处经薄委托零改动**(`ui_click_probe.gd:74/101/112` 直调 `main._camp_data()`×3、`:789` 直调 `main._status_data()`〔iter36 sv7 断言(卡③状态面板瘦身批前缀)〕、`ui_struct_probe.gd:244` 直调 `main._gp_summary_text`——grilling 实查在册,theme_projection_test:810/825 两处注释级引用随动改写) | 三件薄委托保留(零参签名原样转发 HudPresenter 对应静态件);其余直迁 | 探针缝纪律+直引实测清单 | **完成定义**: -1. 四单元落地,main.gd ≤1100 行(行数读数进实现报告); -2. **等价三证**齐(🔴 契约 2):①逐字迁移核对表(逐函数:原行界→新落点,迁移体除接收者/参数化外逐字一致);②全套闸绿(按域选档,本批只碰 `game/`)+改前改后读数对拍;③渲染闸菜单 golden 逐像素不变(判离块在装配/投影路径上的等价证据); -3. 新件合规:`board_resolvers.gd` 头注按库内形制(`##` 载体·S10 闸)+全类型(S9 面)+零禁用词(S11); -4. 至少一条接线变异记录(§7 T2);三份产出物写齐(T3)。 +1. 四单元落地;**行数读数记录**(main 收在 ≈1370–1380、HudPresenter/board_resolvers 各自净增行数)——读数项非停机闸(判离量以函数清单为准,§12 grilling 订正); +2. **等价三证**齐(🔴 契约 2):①逐字迁移核对表(逐函数:原行界→新落点,迁移体除接收者/参数化外逐字一致);②全套闸绿(按域选档,本批只碰 `game/`)+改前改后读数对拍;③渲染闸棋盘三图+菜单 golden 逐像素 changed==0——**resolver 族经 :253-256 注入正是棋盘徽章/数字遮蔽/角标的数据源,在像素路径上**(grilling 归因订正),等价则像素不变; +3. 新件合规:`board_resolvers.gd` 头注库内形制(S10)+全类型(S9)+零禁用词(S11)+S13 基线零新增; +4. 至少一条撤销证明记录(§7 T2——回退本批 hunk 形态);三份产出物写齐(T3)。 ## 2. 设计事实源 | # | 出处 | 取用条款 | |---|---|---| -| D1 | 工程直入证据指认=审计 §三 大文件表 main.gd 行(1508 行;「数据投影族/只读解析回调/文案拼装三件可判离合计 ~440 行;拆后回 ~1070 行;已超架构文档自记的 1100 行上帝对象反面案例」)+本会话结构实查(§3) | 判离块清单与行界 | -| D2 | [architecture](../design/engineering/architecture/architecture.md)「呈现层装配」节 | 组合根职责=接线(构建归屏壳/UiAssembler);探针 `main.X` 句柄路径零迁移;层序唯一事实源 LAYER_CONTRACT 不动 | +| D1 | 工程直入证据指认=审计 §三 大文件表 main.gd 行+本会话结构实查(§3——行数与净判离量按实码重算,审计 ~440 读数不复算成立,订正回呈) | 判离块清单与行界 | +| D2 | [architecture](../design/engineering/architecture/architecture.md)「呈现层装配」节 | 组合根职责=接线(构建归屏壳/UiAssembler);探针 `main.X` 句柄路径零迁移;LAYER_CONTRACT 不动 | | D3 | [code-conventions](../design/engineering/code-conventions.md) §1(结构纪律) | 一个职责一个文件;跨文件迁移禁顺手改写 | +| D4 | 2026-10-24 用户 P0 令 | 行为验收只走撤销证明(回退本批 hunk→红),禁注入造红 | -## 3. 现状事实(2026-10-24 写卡会话主区实查;开工日 T0 复核行号) +## 3. 现状事实(2026-10-24 写卡会话实查+2026-10-25 grilling 实测;开工日 T0 复核行号) | # | 事实 | 出处 | |---|---|---| -| M1 | main.gd 1508 行;函数结构:三族判离块行界——解析回调族 :755-798(四函数连续)、文案两件 :845-866、投影族 :1076-1241(五函数,间隔开窗/关闭处理函数)、`_phase_text` :1393-1401 | `game/presentation/main.gd` 结构图谱(grep ^func 实数) | -| M2 | resolver 注入点:`board_view.set_identity_resolver(_identity_lookup)`(:253)/`set_variant_mask_resolver`(:255)/`set_variant_mark_resolver`(:256)——`_build_ui` 内一次性接线 | `game/presentation/main.gd:253-256` | -| M3 | 解析回调族读态面:`_identity_lookup` 读 `run_scope.settlement.minesweeper`(T0 复核取值链),`_variant_*` 同源;`_debug_hero_override` 读 `debug_overlay` 滑条+meta——四函数依赖面=settlement 只读+debug_overlay+meta | `game/presentation/main.gd:755-798` | -| M4 | HudPresenter 现役形态:static 函数族(`refresh` :10、`feat_holdings_lines`/`tune_sim_report` 等),纯投影/拼装零成员态——承接 r1-1/r1-3 的先例形态 | `game/presentation/hud_presenter.gd:8-12` | -| M5 | 投影族消费面:`_status_data`→status_panel、`_career_data`→career_overlay、`_save_select_data`→save_select_overlay、`_camp_data`→camp_overlay、`_status_curios`→`_status_data` 内部(T0 复核逐投喂点) | `game/presentation/main.gd:1076-1241` | -| M6 | 外部引用面(探针/测试对三族函数名的直引):T0 清单化(grep 探针/测试目录)——预期探针只经 `main.X` 句柄与公开面,私有函数直引为零或极少 | T0 产出 | -| M7 | main.gd 非判离面的近期改动点:卡① d6(:712-717)/d7(:1486-1491)(先落地);`_tune_sim` 构造 :393 | §0 顺序约束 | +| M1 | main.gd 1508 行;三族行界——解析回调族 :755-798(四函数连续,净 ≈44 行)、文案两件 :845-866、投影族五函数 :1076-1241(净 ≈65 行,间隔开窗/关闭处理函数)、`_phase_text` :1393-1401;**净判离合计 ≈140 行**(grilling 逐函数实测) | `game/presentation/main.gd` 结构图谱 | +| M2 | resolver 注入点:`board_view.set_identity_resolver(_identity_lookup)`(:253)/`set_variant_mask_resolver`(:255)/`set_variant_mark_resolver`(:256)——`_build_ui` 内一次性接线;resolver 三函数经此注入是棋盘每格渲染数据源(徽章/数字遮蔽/角标) | `game/presentation/main.gd:253-256` | +| M3 | 解析回调族读态面(两轮复核订正):`_identity_lookup`(:762-772) 三处读 `run_scope.settlement`(:765 `minesweeper.current_board()`/:767 `presentation_snapshot()`/:769 `query_reward_identity()`);`_variant_mask/mark_lookup` 读 `db.variation.row_by_id`;`_debug_hero_override`(:755) 读 `db.hero`+`debug_overlay` 滑条,无 meta | `game/presentation/main.gd:755-798` | +| M4 | HudPresenter 现役形态:static 函数族(`refresh` :12 起、`feat_holdings_lines`/`tune_sim_report` 等),纯投影/拼装零成员态——承接 r1-1/r1-3 的先例形态 | `game/presentation/hud_presenter.gd` | +| M5 | 投影族消费面:`_status_data`→status_panel、`_career_data`→career_overlay、`_save_select_data`→save_select_overlay、`_camp_data`→camp_overlay、`_status_curios`→`_status_data` 内部 | `game/presentation/main.gd:1076-1241` | +| M6 | **探针/测试直引五处在册**(grilling 实查):`ui_click_probe.gd:74/101/112`(`main._camp_data()`×3)、`:789`(`main._status_data()` sv7 直调八键断言,iter36 wc7 刚落)、`ui_struct_probe.gd:244`(`main._gp_summary_text`);另 `theme_projection_test.gd:810/825` 两处注释级同构引用 | 上列 file:line | +| M7 | 卡①触点 :712-717/:1486-1491(先落地);`_tune_sim` 构造 :393;卡②触点 :565 **不在判离块** | §0 | ## 4. 设计契约(红线,违反 = L3 停机呈报) -🔴 **契约 1 · 零行为变更**:判离=逐字等价迁移——函数体除「成员访问改显式参数/接收者」外**逐字一致**;禁顺手重构、禁改名(承接件内函数名保持原名,静态化所需参数化最小化);`LAYER_CONTRACT` 与一切句柄成员零触碰。 +🔴 **契约 1 · 零行为变更**:判离=逐字等价迁移——函数体除「成员访问改显式参数/接收者」外**逐字一致**;禁顺手重构、禁改名(承接件内函数名保持原名,静态化所需参数化最小化);`LAYER_CONTRACT` 与一切句柄成员零触碰;三件薄委托签名与现 main 私有函数逐字同形(`_gp_summary_text` 带参逐字转发——第二轮复核措辞订正)。 -🔴 **契约 2 · 等价三证**:逐字迁移核对表+全套闸绿+菜单 golden 逐像素不变,三证缺一不算完成;棋盘三图 golden 同判(判离块不触棋盘渲染路径,预期零变化——changed>0 即 L3)。 +🔴 **契约 2 · 等价三证**:逐字迁移核对表+全套闸绿+golden(棋盘三图+菜单)逐像素 changed==0,三证缺一不算完成;changed>0 即 L3(resolver 在像素路径上——归因见完成定义 2)。 -🔴 **契约 3 · 探针缝零迁移**:`main.X` 一级句柄路径与探针既有断言零变化;探针/测试对判离函数的直引(M6 清单)同批改引并在实现报告列表;改引后探针全绿。 +🔴 **契约 3 · 探针缝零迁移**:`main.X` 一级句柄路径与探针既有断言零变化;M6 五处直引经薄委托零改动(探针文件本批零改动);theme_projection_test 两处注释级引用随动改写(注释面非断言)。 -🔴 **契约 4 · 新件合规**:`board_resolvers.gd` 一文件一职责(S10 头注 `##` 载体+库内 VERTICAL SLICE 首行形制、S9 全类型、S11 零禁用词);禁把判离块散落多处(r1-2 整族一个文件)。 +🔴 **契约 4 · 新件合规**:`board_resolvers.gd` 一文件一职责(S10 头注+库内 VERTICAL SLICE 首行形制、S9 全类型、S11 零禁用词、S13 基线零新增);禁把判离块散落多处(r1-2 整族一个文件)。 🔴 **契约 5 · LAYER_CONTRACT 与模态登记零触碰**:判离块不含层序/登记逻辑;`_apply_layer_contract` 不动。 ## 5. 范围边界 -**做**:r1-1~r1-4 四单元+等价三证+接线变异一条+产出物。 +**做**:r1-1~r1-4 四单元+等价三证+撤销证明一条+产出物。 -**不做**:main.gd 其余 11 个超线大函数的继续拆分(`_build_ui`/信号处理族留驻——审计仅指认三族);R2/R3 各自文件;卡①缺陷面;§三「其余小件」中 main.gd 死变量/confirm 旁路/settle_batch 空判(未立项,留审计在册)。 +**不做**:main.gd 其余部分的继续拆分(`_build_ui`/信号处理族/开窗关闭处理族留驻——审计仅指认三族;1100 行线的进一步下探待后续批);R2/R3 各自文件;卡①缺陷面;§三「其余小件」中 main.gd 死变量/confirm 旁路/settle_batch 空判(未立项,留审计在册)。 ## 6. 关联文档同步面 @@ -77,9 +80,10 @@ | 文档 | 关联点 | 同步义务 | |---|---|---| -| [architecture](../design/engineering/architecture/architecture.md) 呈现层 D1 行/呈现层装配节 | 新增 `board_resolvers.gd` 拆件+HudPresenter 职责扩列(投影/文案承接)=模块清单变化;架构文档 :149/151「17 项」计数漂移属条目④机械对齐件(本批零触碰、反哺点并呈) | 反哺点 · 列清单(①新件登记+HudPresenter 职责句扩列) | -| `待办清单.md`/`roadmap.md` | 条目拆分注记与迭代行编入笔 | 反哺点 · 列清单(②③) | -| `game/` 探针/测试引用点 | 实施本体 | 实施本体(可写) | +| [architecture](../design/engineering/architecture/architecture.md) 呈现层 D1 行/呈现层装配节 | 新增 `board_resolvers.gd` 拆件+HudPresenter 职责扩列(投影/文案承接)=模块清单变化;架构文档 :149/151「17 项」计数漂移属条目④机械对齐件(零触碰、反哺点并呈) | 反哺点 · 列清单(①新件登记+HudPresenter 职责句扩列) | +| [HUD框架](../design/gdd/systems/表现与支撑/HUD框架.md)(若逐件登记呈现层清单) | 新件一行(T0 核该文档是否列件清单) | 反哺点 · 列清单(②) | +| `待办清单.md`/`roadmap.md` | 条目拆分注记与迭代行编入笔 | 反哺点 · 列清单(③④) | +| `game/` 探针/测试引用点 | 实施本体(本批预期探针零改动,注释级两处随动) | 实施本体(可写) | ## 7. 任务卡 @@ -89,71 +93,75 @@ | 文件 | 职责 | 行为改动 | |---|---|---| -| `game/presentation/main.gd` | 三族判离+留接线委托(复用既有·修改) | 非行为改动(等价迁移)→ wr1 | +| `game/presentation/main.gd` | 三族判离+三件薄委托+调用点改引(复用既有·修改) | 非行为改动(等价迁移)→ wr1 | | `game/presentation/hud_presenter.gd` | r1-1/r1-3 承接(复用既有·扩静态族) | 非行为改动 → wr1 | | `game/presentation/board_resolvers.gd` | **新增**:r1-2 解析回调族承接(新增·新文件) | 非行为改动 → wr1 | -| 探针/测试引用点(M6 清单) | 改引(复用既有·修改) | 非行为改动 → wr1 | +| `game/tests/unit/presentation/theme_projection_test.gd` | 两处注释级引用随动改写(复用既有·改注释) | 非行为改动 → wr1 | ### 接口块 -- `board_resolvers.gd` 形态(命名 L1 可调):`extends RefCounted`;`_init(settlement_getter: Callable, debug_sliders_getter: Callable, meta_override_getter: Callable)`;产出 `identity_lookup(c: Vector2i)`/`variant_mask_lookup(c: Vector2i) -> bool`/`variant_mark_lookup(c: Vector2i) -> String`/`debug_hero_override() -> Dictionary`(签名与现 main 私有函数逐字同形)。 -- HudPresenter 承接函数命名:保持原名(`status_data`/`career_data`/`save_select_data`/`camp_data`/`gp_summary_text`/`bonus_summary_text`/`phase_text`——去下划线前缀入静态族,参数表显式化;命名差异属 L1)。 -- 最窄闸:探针族=`tools/probe_gate.sh` 对应段单跑;单测=`--script` 单件直跑;渲染=`tools/render_gate.sh`。 +- `board_resolvers.gd` 形态(命名 L1 可调):`extends RefCounted`;`_init(db_ref, debug_overlay_ref, settlement_getter: Callable)`(依赖面=M3 实查——db+调试滑条+settlement 活态取值〔`_identity_lookup` 三读 settlement〕;无 meta);产出 `identity_lookup(c: Vector2i) -> Variant`/`variant_mask_lookup(c: Vector2i) -> bool`/`variant_mark_lookup(c: Vector2i) -> String`/`debug_hero_override() -> Dictionary`(签名与现 main 私有函数逐字同形,返回类型按现体实态补全)。 +- HudPresenter 承接函数命名:保持原名去下划线入静态族(`status_data`/`status_curios`/`career_data`/`save_select_data`/`camp_data`/`gp_summary_text`/`bonus_summary_text`/`phase_text`),参数表显式化(取值面=M5 消费链:db/save/meta/runner 状态由调用侧传参);命名差异属 L1。 +- 三件薄委托(main 内保留,签名逐字同形零参转发):`_camp_data()`/`_status_data()`/`_gp_summary_text()`——探针直引零改动的承载面;`_status_curios` 为 `_status_data` 内部调用,随委托链走(grilling 行数账注:委托回填 ≈12 行)。 +- 最窄闸:探针族=`tools/probe_gate.sh` 对应段单跑;单测=`--script` 单件直跑+`tools/error_scan.py` 判红口径;渲染=`tools/render_gate.sh`。 ### 落位与可复用性预检 -- **`board_resolvers.gd`(新文件)**——复用面:为什么不并入 HudPresenter:解析回调是**有态绑定件**(构造注入取值 Callable、产出绑定闭包),HudPresenter 是无态静态族——混装破坏两者形态纪律;为什么不留在 main:审计判离指认+组合根只接线原则。唯一面:board_view 三个 resolver 的唯一供给源(注入点 :253-256 单点)。分层与交互面:presentation 层内部件,零 core 依赖(读 settlement 只读快照经注入面),零新跨层出口。 +- **`board_resolvers.gd`(新文件)**——复用面:为什么不并入 HudPresenter:解析回调是**有态绑定件**(构造注入 db/滑条、产出绑定 Callable),HudPresenter 是无态静态族——混装破坏两者形态纪律;为什么不留在 main:审计判离指认+组合根只接线原则。唯一面:board_view 三个 resolver 的唯一供给源(注入点 :253-256 单点)。分层与交互面:presentation 层内部件,零 core 依赖(读 db 与调试滑条),零新跨层出口。 - **HudPresenter 扩列**——复用面:既有静态投影/拼装宿主(M4),扩列即复用不新立;唯一面:投影/文案承接后仍是唯一宿主(与 board_resolvers 职责互斥:静态投影 vs 有态绑定)。 -- **零新增函数体**:全部迁移体为既有函数逐字搬运。 +- **三件薄委托**——为什么留:探针五处直引(M6)零改动的最小承载;备选「探针改引」淘汰依据=探针缝纪律(探针文件零改动优先)。 +- **零新增函数体**:全部迁移体为既有函数逐字搬运(薄委托为三行转发体)。 ### T0 事实坐实(≈0.25d) -- [ ] 复核 M1-M6(重点:M3 取值链、M5 投喂点、M6 外部直引清单——grep `game/probe/ game/tests/ game/sim/` 对五投影/四回调/三文案函数名)。可核查结果:外部直引清单+行界漂移声明进实现报告素材。 +- [ ] 复核 M1-M7(重点:M3 `_identity_lookup` 取值链实读;M6 五处直引现址复核;行号漂移)。可核查结果:直引清单+漂移声明进实现报告素材。 - [ ] 改前读数(main.gd 行数、探针/单测/golden 通过数)。可核查结果:基线表在案。 -### T1 三族判离+改引(≈0.75–1d) +### T1 三族判离+改引(≈0.75d) -- [ ] 实装 r1-2(board_resolvers 新件+:253-256 注入改引)→ r1-1/r1-3(HudPresenter 扩列+main 调用点改引)→ r1-4(外部引用点改引)。可核查结果:main.gd ≤1100 行;`git diff` 迁移体逐字一致(核对表逐函数行界对)。 -- [ ] 验收步骤:全套闸按域选档跑一次全绿+菜单/棋盘 golden 逐像素不变(changed==0 预期——非 0 即 L3)。 +- [ ] 实装 r1-2(board_resolvers 新件+:253-256 注入改引)→ r1-1/r1-3(HudPresenter 扩列+main 调用点改引)→ r1-4(三件薄委托+theme_projection_test 注释随动)。可核查结果:`git diff` 迁移体逐字一致(核对表逐函数行界对);行数读数记录(预期 ≈1370–1380)。 +- [ ] 验收步骤:全套闸按域选档跑一次全绿+棋盘三图与菜单 golden changed==0(契约 2——非 0 即 L3)+探针全绿(M6 五处直引零改动即绿)。 -### T2 接线变异+产出物落位卡(≈0.25d,末卡) +### T2 撤销证明+产出物落位卡(≈0.25d,末卡) -- [ ] 接线变异一条(test-conventions §9.4「每张任务卡至少一条撤销或变异」):临时把 :253 注入改回直引旧路形态外的错指(如断开 identity 注入)→ 对应探针/断言红 → 还原复绿。记录进实现报告。 +- [ ] 撤销证明一条(P0 令形态——只回退本批 hunk):回退 HudPresenter 承接件任一函数 hunk(如 `gp_summary_text` 承接体)→ main 委托/调用点引用未定义符号 → 单测/探针直跑输出经 `tools/error_scan.py` 扫出 SCRIPT ERROR 红 → 精确还原复绿。记录进实现报告。 - [ ] 写齐三份:`reports/iter-实现报告-<完成日>.md`(逐字迁移核对表+行数读数+golden 读数+实机目检总清单〔三屏开合与状态面板/生涯/选档/营地投喂抽查〕)/代拍板追认单/反哺点(§6 各条落点)。 - [ ] 合并前置:独立验收审计(未参与实现的会话/子代理,只读本卡/diff/测试件+抽查迁移体逐字一致性)报告逐行「通过」。 -**估时合计 ≈1.25–1.5d**。编排注记:前置卡①落地后开工;估时低于 iter-plan 硬下限,与 R2/R3 或他卡同批编入。 +**估时合计 ≈1.25d**。编排注记:前置卡①落地后开工;估时低于 iter-plan 硬下限,与 R2/R3 或他卡同批编入。 ## 8. 验证闸 ### 改动—验收对照表 -| 需求点 | 改动 | 验收测试(尾缀) | 层级 | 真实入口 | 变异/撤销证明 | +| 需求点 | 改动 | 验收测试(尾缀) | 层级 | 真实入口 | 撤销证明 | |---|---|---|---|---|---| -| wr1 三族判离等价 | main.gd 三族迁出+改引 | 全套闸绿+golden changed==0+逐字迁移核对表〔wr1〕 | 集成+渲染 | 探针真实驱动路径+面板真实投喂链 | 接线变异一条(T2);等价三证替代逐单元撤销(等价重构申报) | -| wr2 新件合规 | board_resolvers.gd | S9/S10/S11 三闸零命中〔wr2〕 | 静态扫描 | 闸真实跑批 | 回退头注/类型 → 对应闸红 | +| wr1 三族判离等价 | main.gd 三族迁出+薄委托+改引 | 全套闸绿+golden changed==0+逐字迁移核对表〔wr1〕 | 集成+渲染 | 探针真实驱动路径(五直引零改动)+面板真实投喂链 | 撤销证明一条(T2——回退承接 hunk→error_scan 红);等价三证替代逐单元撤销(等价重构申报) | +| wr2 新件合规 | board_resolvers.gd | S9/S10/S11/S13 四闸零命中〔wr2〕 | 静态扫描 | 闸真实跑批 | 回退头注/类型 → 对应闸红 | | wr3 产出物 | T2 三份 | 件核对〔wr3〕 | — | — | 缺项红 | -**测试削弱申报**:零(既有断言零改动——改引仅换址不改判据)。**独立验收审计**:同卡① §8.3 口径。 +**测试削弱申报**:零(既有断言零改动——theme_projection_test 两处为注释级随动)。**独立验收审计**:同卡① §8.3 口径。 ## 9. 异常分级 - **L1(自救)**:承接件命名(去下划线入静态族等);参数化的最小形态。 -- **L2(记录继续)**:M6 外部直引清单的个别改引适配。 -- **L3(停机呈报)**:迁移体无法逐字等价(依赖面比 M3 宽——判离指认失真,回呈审计结论);golden changed>0;任一探针/套件出非本批存量红;main ≤1100 行达不成(判离量不足——呈报是否再切,禁批内自扩范围)。 +- **L2(记录继续)**:行数读数与 ≈1370–1380 预期的正常偏差(判离量以函数清单为准)。 +- **L3(停机呈报)**:迁移体无法逐字等价(依赖面比 M3 宽——判离指认失真,回呈审计结论);golden changed>0;任一探针/套件出非本批存量红(含 M6 直引处变红)。 ## 10. 代拍板白名单 1. board_resolvers.gd 与承接函数命名(接口块签名语义不变前提)。 -2. 参数化取值 Callable 的具体形态。 +2. 参数化取值的具体形态。 3. 提交切分与 worktree 分支命名。 ## 11. 待裁点 -**零待裁点,开工门=U0。** 一处灰色地带推导定值:解析回调族落**新件**而非 HudPresenter——依据=有态绑定件与无态静态族的形态纪律(预检节);备选「并入 HudPresenter」淘汰依据=形态混装。用户可否决(随 T2 反哺点呈报)。 +**零待裁点,开工门=U0。** 一处灰色地带推导定值:解析回调族落**新件**而非 HudPresenter——依据=有态绑定件与无态静态族的形态纪律(预检节);备选「并入 HudPresenter」淘汰依据=形态混装。另一处:探针直引面走**薄委托**而非探针改引——依据=探针缝纪律(探针零改动优先);备选「探针改引」淘汰依据=改探针引入额外验证面。两处均呈报可否决(随 T2 反哺点)。 ## 12. 自审六查与 grilling 复核记录 -**自审六查(2026-10-24 写卡会话)**:①规格覆盖——r1-1~r1-4→T1、合规/变异/产出物→T2,指到 wr1–wr3;②步骤扫描——一步一动作一可核查结果;③类型一致性——接口块签名与 M1-M5 实查一致;④审查焦点——补挂:探针缝断言零变化(契约 3)、golden 双基线判据(契约 2)、外部直引清单义务(M6/T0);⑤篇幅比例——重构卡无实现体抄写;⑥落位预检——新件唯一性与 HudPresenter 复用理由已答。 +**自审六查(2026-10-24 写卡会话)**:①规格覆盖——r1-1~r1-4→T1、合规/撤销/产出物→T2,指到 wr1–wr3;②步骤扫描——一步一动作一可核查结果;③类型一致性——接口块签名与 M1-M6 实查一致;④审查焦点——探针直引五处(M6→薄委托)、golden 归因(resolver 在像素路径——契约 2)、iter36 迁移基线换代;⑤篇幅比例——重构卡零实现体;⑥落位预检——新件唯一性、HudPresenter 复用、薄委托理由已答。 -**grilling 复核记录**:v1.0 成文后独立子代理对抗复核——记录见本节(复核后补写)。 +**grilling 第一轮复核记录(2026-10-25,独立子代理对抗复核)**:判回炉两阻断——R1-A1 行数目标与判离清单算术断裂(实查净判离 ≈140 行,≤1100 差约 260 行不可达,审计 ~440/1070 读数自身不成立);R1-A2 T2「接线变异」违 2026-10-24 P0 令。随同五应修(F1 M6 直引五处实测在册;F2 依赖面错位〔meta→实为 db〕;F3 golden 归因失真〔resolver 在像素路径〕;F4 :565 不随迁误述;F5 iter36 已入库且 `_status_curios` 参数化交叠)。v1.1 全部折入:行数账按实码重算(≈1370–1380 读数记录、1100 线下探移出范围、审计读数订正回呈)、证明改撤销形态(回退承接 hunk→error_scan 红)、依赖面/golden 归因/:516 直引清单/iter36 基线换代全部订正、薄委托方案定案(§11 呈报)。复核结论:两阻断闭合、五应修落位。 + +**grilling 第二轮复核记录(2026-10-25,同代理续核)**:总判**通过(附应修)**——第一轮两阻断真闭合、行数账自洽、证明形态合规、薄委托方案成立。新发现一条应修(接口块 v1.1 修订时把 v1.0 原本正确的 settlement 注入弄丢——`_identity_lookup` 三处读 `run_scope.settlement`,两参注入面无法支撑)+两条建议(M6「wc7」实为 sv7;「零参转发」对带参 `_gp_summary_text` 不精确)。v1.2 折入:接口块/M3/r1-2 恢复 settlement 取值面(三参注入)、sv7 订正、「签名逐字同形转发」措辞。零待裁点成立,卡进可编排态。 diff --git a/reports/需求卡片-重构runner拆件与断点schema单点批-2026-10-24.md b/reports/需求卡片-重构runner拆件与断点schema单点批-2026-10-24.md index dc5a337f..0a7498eb 100644 --- a/reports/需求卡片-重构runner拆件与断点schema单点批-2026-10-24.md +++ b/reports/需求卡片-重构runner拆件与断点schema单点批-2026-10-24.md @@ -1,71 +1,74 @@ -# 需求卡片:重构 runner 拆件与断点 schema 单点批(CurioDeck+商店子系统+断点字段单源) +# 需求卡片:重构 runner 拆件与断点 schema 单点批(CurioDeck+商店件+断点字段单源) -- 版本:**v1.0**(2026-10-24 成文;grilling 复核记录见 §12) -- 来源:[待办清单](../待办清单.md)「game 代码结构审查批——行为缺陷定点修+结构重构候选」条目之结构重构候选(2026-10-24 用户裁**五件全部立项**,本卡收 adventure_runner 令牌池拆件+level_runner 商店拆件+断点 schema 单点化三件)(唯一事实源:工程直入证据指认=审计报告 [reports/审计-game代码结构审查-2026-10-24.md](审计-game代码结构审查-2026-10-24.md) §三 大文件表 adventure_runner/level_runner 行+断点 schema 三处重复登记段+本写卡会话结构实查〔本卡 §3〕) -- 归属:`game/core/adventure_runner.gd`(令牌池拆出源)+ `game/core/level_runner.gd`(商店拆出源)+ `game/core/curio_deck.gd`(**新增**·令牌池件)+ `game/core/shop_session.gd`(**新增**·商店子系统件,命名 L1 可调)+ 断点 schema 单源常量(落 adventure_runner 或独立件,T0 定)+ 断点域测试面 -- 排期:未编入(迭代批卡片;估时 ≈2–2.5 工作日);**前置=卡①先行落地**(其 ⑧ 表读触点在商店子系统内) +- 版本:**v1.2**(2026-10-24 v1.0 成文→2026-10-25 grilling 第一轮修订 v1.1〔两阻断+五应修折入〕→第二轮复核「通过(附应修)」,两条应修(行数读数按新边界重算/契约 5 接线行例外)折入定稿;复核结论见 §12) +- 来源:[待办清单](../待办清单.md)「game 代码结构审查批——行为缺陷定点修+结构重构候选」条目之结构重构候选(2026-10-24 用户裁**五件全部立项**,本卡收 adventure_runner 令牌池拆件+level_runner 商店拆件+断点 schema 单点化三件)(唯一事实源:工程直入证据指认=审计报告 [reports/审计-game代码结构审查-2026-10-24.md](审计-game代码结构审查-2026-10-24.md) §三 大文件表 adventure_runner/level_runner 行+断点 schema 段+本写卡会话结构实查〔本卡 §3——审计「断点三处重复登记」经实查**save 侧零键登记**,「三处」订正为写/读两侧,§12 回呈〕) +- 归属:`game/core/adventure_runner.gd`(令牌池拆出源)+ `game/core/level_runner.gd`(商店拆出源)+ `game/core/curio_deck.gd`(**新增**·令牌池件)+ `game/core/shop_session.gd`(**新增**·商店件,命名 L1 可调)+ 断点字段单源(宿主内 const,§11 定值)+ 断点域测试面 +- 排期:未编入(迭代批卡片;估时 ≈2–2.5 工作日);**前置=卡①先行落地**(其 d11 表读触点在商店族内) - 开工门:U0+grilling 复核门过(§12) ## 0. 前置依赖与并行性 - **第〇步核对(2026-10-24 写卡会话)**:来源条目设计面=工程直入、状态=待写卡;重构候选 2026-10-24 用户裁全部立项——工程直入重构类,凭审计 §三行号级证据放行。 -- **顺序硬约束**:卡①先行(d11 表读替换落在 `_spend_discounted`/`pool_price` 内——先修后迁,迁移体带上修好的表读形态);卡② S9 注解若先行,两 runner 位点注解随迁。R3 晚于 R1/R2 开工非硬约束(零文件交叠,可并行波)。 -- **断点兼容硬约束**:断点 schema 单点化**不改任何键名/缺省值/回退语义**——旧档(含 v6/v7 迁移链在档存档)读取行为逐位不变;`breakpoint_resume_test` 与断点域既有单测是回归主线。 +- **顺序硬约束**:卡①先行(d11 表读替换落在 `_spend_discounted`/`pool_price` 内——先修后迁,迁移体带上修好的表读形态);卡②注解若先行随迁。R1/R2 零文件交叠,可并行波。 +- **与迭代 36(已实现入库)**:iter36 卡C wc2 落「断点快照喂入→`resume_adventure` :151-154 真链回填、run_ledger.bonus.atk==5」续玩断言(ui_click_probe)——**现役最强断点行为回归,纳入 T0 基线与本批回归面**;本批触 `resume_adventure` 读写侧,该断言必须全程绿。 +- **断点兼容硬约束**:断点单点化**不改任何键名/缺省值/回退语义**——旧档读取行为逐位不变;`breakpoint_resume_test`+iter36 wc2 断言是回归主线。 +- **gdstyle S13(已落地)**:两新 core 件落在 S13 扫描面——基线零新增。 ## 1. 目标与完成定义 -**目标**:①adventure_runner(1049 行)的令牌池子系统(构建/抽签/cap/凭证,~500 行)拆出为 `curio_deck.gd`;②level_runner(1012 行)的商店子系统(legacy+pool 双模式,~260 行)拆出为 `shop_session.gd`;③断点 schema 三处重复登记(`_snapshot_breakpoint` 写/`resume_adventure` 读/save 侧默认值)单点化为字段登记单源——三件全零行为变更,断点档与续玩行为逐位不变。 +**目标**:①adventure_runner(1049 行)的**池与判定面**(令牌多重集/抽签/cap/凭证判定/库存查询,≈340 行)拆出为 `curio_deck.gd`——**停点编排与兑付推进面留宿主**(边界见 r3-1);②level_runner(1012 行)的商店族(21 函数,≈260 行)拆出为 `shop_session.gd`;③断点 schema 写/读两侧重复登记单点化为字段登记单源——三件全零行为变更,断点档与续玩行为逐位不变。 **改动单元清单**(🔴 契约 1): | # | 单元(实查) | 改法 | 依据 | |---|---|---|---| -| r3-1 | 令牌池族:成员 `_curio_deck`(:60)/`_curio_taken`(:59)/`_feat_ticket_pity`(:67)/`_feat_ticket_sold`(:68)/`_feat_ticket_appeared`(:69)+函数族 `_reset_curio_state`(:247)/`_build_curio_deck`(:265)/`_token_identity`(:279)/`skip_empty_curio`(:334)/`_find_token`(:346)/`pick_curio`(:361)/`pool_stock`(:461)/`_consume_pool_purchase`(:473)/`_pool_stock_snapshot`(:484)/`_finish_curio_pick`(:494)/`node_curio_candidates`(:513)/`present_node_curio`(:518)/`apply_node_curio`(:525)/refresh 族(:556-641)/`_finish_node_bonus`(:643)/`_draw_curio_candidates`(:669)/`_curio_cap_ok`(:757)/`_feat_ticket_consider`(:772)/`_redeem_feat_ticket`(:789) | 拆出 `curio_deck.gd`:令牌多重集+kind 计数+凭证三计数+抽签/cap/凭证判定逻辑入件;宿主记账(run_ledger/ledger/summary/断点附随)经回调或显式参数——**停点编排与兑付推进留宿主**(拆「池与判定」不拆「停点流程」);AdventureRunner 成员持用+公开面委托保持原签名(外部调用面零变化) | 审计 §三「令牌池子系统(构建/抽签/cap/凭证,~500 行)自成一体可拆 CurioDeck 类」 | -| r3-2 | 商店族:`shop_products`(:753)/`current_price`(:769)/`_spend_discounted`(:777)/`purchased_tier`(:783)/`buy_product`(:789)/`player_request_refresh`(:812)/`set_shop_pool`(:823)/`_shop_open_pool`(:832)/`_shop_draw_shelf`(:843)/`pool_stock`(:880)/`pool_price`(:891)/`shop_shelf`(:905)/`shop_refresh_free_left`(:932)/`_attune_shop_refresh_bonus`(:939)/`shop_refresh_cost`(:948)/`shop_refresh`(:953)/`spend_gp`(:967)/`buy_pool_item`(:977)/`is_shop_pool`(:1002)/`shop_bp_shelf`(:1007)/`shop_bp_visit_buys`(:1011)+成员 `_shop_*`(:37/:49-56) | 拆出 `shop_session.gd`:双模式货架/定价/购买/刷新入件(db 注入+池回调注入沿用 `set_shop_pool` 既有 Callable 面);LevelRunner 公开面委托保持原签名(main/presenter/测试调用面零变化);钱包出入账留宿主(`_gain_wallet`/`close_wallet` 不迁) | 审计 §三「商店子系统(legacy+pool 双模式,~260 行)可拆」 | -| r3-3 | 断点 schema 三处:写侧 `_snapshot_breakpoint`(:990-1034,28 键字典逐键手拼)/读侧 `resume_adventure`(:140-246 逐键取值+缺省回退)/save 侧默认(`save_manager.gd:218-219/298/595-607` 断点域操作面;第三处枚举位 T0 精确定位——审计原述「save 默认值」) | 单源化:字段登记单源(`const BREAKPOINT_FIELDS`——键→{缺省, 是否 deep duplicate},形态 L1)驱动写侧(逐键取值器表)与读侧(缺省回退表);三处改由单源派生。**键集/缺省值/回退语义逐键冻结**(28 键清单=写侧 :1000-1030 实查全集) | 审计 §三「断点 schema 三处重复登记,每加一字段改三处,散弹式修改热点」 | +| r3-1 | **迁出面**(池与判定):成员 `_curio_deck`(:60)/`_curio_taken`(:59)/`_feat_ticket_pity`(:67)/`_feat_ticket_sold`(:68)/`_feat_ticket_appeared`(:69)+函数 `_build_curio_deck`(:265)/`_token_identity`(:279)/`_find_token`(:346)/`pool_stock`(:461)/`_consume_pool_purchase`(:473)/`_pool_stock_snapshot`(:484)/`_consume_deck_token`(:440-452,grilling 补入——纯池摘牌,不迁则件内池被宿主直改=双写)/`_draw_curio_candidates`(:669)/`_curio_cap_ok`(:757)/`_feat_ticket_consider`(:772)+`_reset_curio_state`(:247) 的池半(件内 `reset()` 承载,宿主复位停点态)。**留宿主面**(停点编排与兑付推进):`skip_empty_curio`(:334)/`pick_curio`(:361)/`_feat_payload_keys`(:381)/`_apply_curio_pick`(:393)/`_finish_curio_pick`(:494)/`node_curio_candidates`(:513)/`present_node_curio`(:518)/`apply_node_curio`(:525)/refresh 族(:556-641,读写 `_attune_refresh_x`/`_refresh_stock`/`_node_curio_pending` 停点态——**断点时点 :634 住在 `_refresh_curio_common` 体内**)/`_finish_node_bonus`(:643)/`_redeem_feat_ticket`(:789,兑付推进——**断点时点 :803 住其体内**);另 `feats_held`(:453) 读宿主 `_feats` 留驻(持有集查询,非池面) | 拆出 `curio_deck.gd`:令牌多重集+kind 计数+凭证三计数+抽签/cap/凭证判定入件;宿主公开面委托保持原签名(外部调用面零变化);AdventureRunner 行数读数预期 **≈850±10**(第二轮按 v1.1 边界清单重算:迁出 ≈211 行+委托与 Callable 绑定回填 ≈15–25——第一轮 709 系「只留 refresh 族」旧口径,随边界扩到兑付推进族作废;**读数项非停机闸**) | 审计 §三「令牌池子系统(构建/抽签/cap/凭证,~500 行)」指认——**边界经 grilling R3-A1 重划**(全族含 refresh 迁则断点时点被扰动、违零变更;拆「池与判定」不拆「停点编排」) | +| r3-2 | 商店族 21 函数(`shop_products`(:753)/`current_price`(:769)/`_spend_discounted`(:777)/`purchased_tier`(:783)/`buy_product`(:789)/`player_request_refresh`(:812)/`set_shop_pool`(:823)/`_shop_open_pool`(:832)/`_shop_draw_shelf`(:843)/`pool_stock`(:880)/`pool_price`(:891)/`shop_shelf`(:905)/`shop_refresh_free_left`(:932)/`_attune_shop_refresh_bonus`(:939)/`shop_refresh_cost`(:948)/`shop_refresh`(:953)/`spend_gp`(:967)/`buy_pool_item`(:977)/`is_shop_pool`(:1002)/`shop_bp_shelf`(:1007)/`shop_bp_visit_buys`(:1011))+成员 `_shop_*`(:37/:49-56)——**以函数清单为准**(:715-1011 区间内 `grant_curio_gp`/`continue_after_node` 等非商店函数不迁) | 拆出 `shop_session.gd`:双模式货架/定价/购买/刷新入件(db 注入+`set_shop_pool` 既有四参 Callable 面沿用,缺省值 `Callable()` 逐字对齐 :823);LevelRunner 公开面委托保持原签名;钱包原语 `_gain_wallet`/`close_wallet` 留宿主(`spend_gp` 随件迁、经回调落宿主账本——§11 定值);level_runner 读数预期 ≈780 | 审计 §三「商店子系统(legacy+pool 双模式,~260 行)可拆」 | +| r3-3 | 断点 schema **写/读两侧**(grilling 订正:审计「三处」的 save 侧经实查**零键登记**——:218-219/:298 只置空字典、:595-607 四口值拷贝,无字段枚举=空派生不动):写侧 `_snapshot_breakpoint`(:990-1034,**27 顶层键**——bonus 含 4 子键;v1.0「28 键」计数订正);读侧两消费位=`resume_adventure`(:140-246)+`_start_current_level` 二次消费(`node_id`/`visited_ids`/`template_pick`/`aux_items` 四键经 `_resume_bp` 在 :854-860/:875-877,grilling 补查——v1.0 漏记) | 单源化:宿主内 `const BREAKPOINT_FIELDS`(键→登记项:写侧取值器+读侧回退策略标签)驱动写侧拼装与**两处**读侧回退;**读侧回退策略按实语义逐键归类**(grilling R3-F2 五类:plain 缺省/null 类型守卫保持既有态〔bonus_deck/adventure_counters/attunement_charges :174/:223/:241〕/双向合并〔bonus_taken :162-165〕/钳制〔bonus 子键 maxi(0)、hero_hp :192-193〕/参数面回退〔attune_refresh_y :205〕/令牌化迁移〔bonus_pending.candidates :230-240〕)——`{default, deep}` 双字段表达不了的面按策略标签登记;save 侧经核零改动 | 审计 §三「断点 schema 三处重复登记,每加一字段改三处」——写/读两侧单源化即消散弹面;save 侧论断不成立(§12 回呈) | **完成定义**: -1. 三单元落地:adventure_runner ≤650 行、level_runner ≤800 行(读数进实现报告); -2. 等价三证齐:①逐字迁移核对表(两拆件族)+断点单源对照表(28 键逐键:缺省值/回退语义改前改后一致);②全套闸绿+读数对拍;③断点专项:`breakpoint_resume_test` 绿+旧档读取回归(构造缺键旧档断点→续玩回退行为与改前一致——按既有测试面扩一条缺键回退断言,判据从写侧 :1000-1030 缺省值推导); -3. 两新件+单源常量合规(S9/S10/S11;core 域零 UI 零 await 零裸随机——S1-S5 全过); -4. 至少一条接线变异记录;三份产出物写齐(T3)。 +1. 三单元落地;**行数读数记录**(adventure_runner ≈710–730/level_runner ≈780/两新件净行数——读数项非停机闸,判离量以函数清单为准); +2. 等价三证齐:①逐字迁移核对表(两拆件族)+断点单源对照表(**27 顶层键逐键:缺省值/回退策略改前改后一致**);②全套闸绿+读数对拍;③断点专项:`breakpoint_resume_test` 绿+iter36 wc2 续玩断言(ui_click_probe)绿+新增断言「单源键集==写侧字典键集」(wr2——判据从写侧实拼字典推导); +3. 两新件+单源合规(S9/S10/S11/S13+core 域 S1-S5:零 UI 零 await 零裸随机零表直读); +4. 至少两条撤销证明记录(T3);三份产出物写齐(T3)。 ## 2. 设计事实源 | # | 出处 | 取用条款 | |---|---|---| -| D1 | 工程直入证据指认=审计 §三 adventure_runner/level_runner 行+断点 schema 段+本会话结构实查(§3) | 三单元清单与行界 | +| D1 | 工程直入证据指认=审计 §三 adventure_runner/level_runner 行+断点 schema 段+本会话结构实查(§3——边界经 grilling 重划、save 侧论断订正) | 三单元清单与边界 | | D2 | [architecture](../design/engineering/architecture/architecture.md) 核心层纪律+「战斗域装配现状」节 RunLedger 先例 | core 件零引擎依赖;共享账经显式类/引用不隐式——r3-1 宿主记账回调化的依据 | -| D3 | [code-conventions](../design/engineering/code-conventions.md) §1/§2.4 | 一文件一职责;状态字段语义显式(断点单源的缺省表=语义显式化) | +| D3 | [code-conventions](../design/engineering/code-conventions.md) §1/§2.4 | 一文件一职责;状态字段语义显式(断点单源=语义显式化) | | D4 | [存档序列化](../design/gdd/systems/表现与支撑/存档序列化.md) | 断点域契约(SCHEMA_VERSION+快照锚)——键集冻结的规范面 | +| D5 | 2026-10-24 用户 P0 令 | 行为验收只走撤销证明,禁注入造红 | -## 3. 现状事实(2026-10-24 写卡会话主区实查;开工日 T0 复核行号) +## 3. 现状事实(2026-10-24 写卡会话实查+2026-10-25 grilling 实测;开工日 T0 复核行号) | # | 事实 | 出处 | |---|---|---| -| A1 | adventure_runner 1049 行;令牌池族成员五处+函数 19 个(r3-1 清单);与宿主态的耦合面:`_finish_curio_pick`/`_finish_node_bonus` 写 run_ledger.bonus 与 ledger、`_draw_curio_candidates` 读 `_feat_ticket_*` 三计数、refresh 族写 `_attune_refresh_x`/`_refresh_stock`(停点态留宿主的边界依据) | `game/core/adventure_runner.gd:59-70/247-279/334-381/461-544/556-641/643-676/757-810` | -| A2 | level_runner 1012 行;商店族成员+函数 21 个(r3-2 清单);`set_shop_pool`(:823) 既有四参注入面(deck 引用+consume/ticket/cap 三 Callable)=拆件回调面的现成形态;钱包 `_gain_wallet`(:738)/`close_wallet`(:745)/`spend_gp`(:967) 边界——spend_gp 属钱包面但只服务商店扣款(T0 定去留:倾向随件迁、宿主留账本原语) | `game/core/level_runner.gd:37/49-56/715-1011` | -| A3 | 断点写侧 28 键字典(:1000-1030 逐键实查:level_index/node_id/hero_hp/bonus{4 子键}/gp/shop_purchased/shop_shelf/shop_visit_buys/attunement_charges/template_pick/master_seed/rng_counter/keystone/visited_ids/aux_items/bonus_taken/bonus_deck/relics/bonus_pending/feat_ticket_pity/feat_ticket_sold/adventure_counters/vision_counter_used/refresh_stock/attune_refresh_y/bonus_result/keystone_drops);读侧 :140-246 逐键 `bp.get(键, 缺省)`;save 侧 :218-219(缺 breakpoint 补 `{}`)/:298(默认 `{}`)/:595-607(set/clear/has/snapshot 四口) | `game/core/adventure_runner.gd:140-246/990-1034`;`game/core/save_manager.gd:218-219/298/595-607` | -| A4 | 断点域测试面:`breakpoint_resume_test.gd` 在役(续玩回退/不重兑付面);`_snapshot_breakpoint` 调用点五处(:506/:634/:803/:933/:982——停点快照时点集) | `game/tests/unit/core/breakpoint_resume_test.gd`;`game/core/adventure_runner.gd:506/634/803/933/982` | -| A5 | 外部调用面:LevelRunner 商店/池面消费方=main.gd+camp_shop_presenter/curio_interact_controller(呈现侧)+level_shop_economy_test/curio_refresh_paid_test/pool_case_d_test 等;AdventureRunner 令牌面消费方=main/控制器+断点域测试——公开签名零变化=外部零改动的依据 | T0 直引清单化 | -| A6 | 卡① d11 触点 `pool_price`(:891)/`_spend_discounted`(:777) 在商店族内(先修后迁);`shop_bp_shelf`/`shop_bp_visit_buys`(:1007/:1011) 是断点附随取数面(r3-2 与 r3-3 的交点——随商店件迁、断点写侧经其公开面取数不变) | 卡① §1 d11;`game/core/level_runner.gd:1007-1011` | +| A1 | adventure_runner 1049 行;池与判定面(r3-1 迁出清单)与停点编排面(留宿主清单)的分界依据:refresh 族读写 `_attune_refresh_x`(:49)/`_refresh_stock`(:53)/`_node_curio_pending`(:63) 停点态、`_finish_curio_pick`/`_finish_node_bonus` 写 run_ledger.bonus 与 ledger、`_redeem_feat_ticket` 兑付推进——**断点五时点之三住在留宿主函数体内**(:506 在 `_finish_curio_pick`、:634 在 `_refresh_curio_common`、:803 在 `_redeem_feat_ticket`) | `game/core/adventure_runner.gd:49/53/63/247-810/990-1034` | +| A2 | level_runner 1012 行;商店族 21 函数清单(r3-2,函数清单为准);`set_shop_pool`(:823) 四参注入面(deck 引用+consume/ticket/cap 三 Callable,后两参缺省 `Callable()`)=拆件回调面的现成形态;钱包边界=`_gain_wallet`(:738)/`close_wallet`(:745) 宿主留、`spend_gp`(:967) 只服务商店扣款 | `game/core/level_runner.gd:37/49-56/715-1011` | +| A3 | 断点写侧 **27 顶层键**(:1001-1030 逐键实查:level_index/node_id/hero_hp/bonus{atk,max_hp,armor_class,ap 四子键}/gp/shop_purchased/shop_shelf/shop_visit_buys/attunement_charges/template_pick/master_seed/rng_counter/keystone/visited_ids/aux_items/bonus_taken/bonus_deck/relics/bonus_pending/feat_ticket_pity/feat_ticket_sold/adventure_counters/vision_counter_used/refresh_stock/attune_refresh_y/bonus_result/keystone_drops);读侧消费**两处**:`resume_adventure`(:140-246——五类回退策略实语义见 r3-3)+`_start_current_level` 经 `_resume_bp` 四键二次消费(:854-860/:875-877);save 侧 :218-219/:298/:595-607 **零键登记**(空字典与值拷贝) | `game/core/adventure_runner.gd:140-246/990-1034`;`game/core/save_manager.gd:218-219/298/595-607` | +| A4 | 断点五时点集::506/:634/:803/:933/:982——**全部住在留宿主函数体内**(A1),拆件不扰动时点形态 | `game/core/adventure_runner.gd:506/634/803/933/982` | +| A5 | 外部调用面:LevelRunner 商店/池面消费方=main.gd+camp_shop_presenter/curio_interact_controller(呈现侧)+level_shop_economy_test/curio_refresh_paid_test/pool_case_d_test 等;AdventureRunner 令牌面消费方=main/控制器+断点域测试——公开签名零变化=外部零改动的依据;iter36 wc2 断点续玩断言在 `ui_click_probe`(断点快照喂入→resume 真链→run_ledger.bonus.atk==5) | T0 直引清单化;`game/probe/ui_click_probe.gd`(iter36 wc2 段) | +| A6 | 卡① d11 触点 `pool_price`(:891)/`_spend_discounted`(:777) 在商店族内(先修后迁);`shop_bp_shelf`/`shop_bp_visit_buys`(:1007/:1011) 是断点附随取数面(随商店件迁、断点写侧经其公开面取数不变) | 卡① §1 d11;`game/core/level_runner.gd:1007-1011` | ## 4. 设计契约(红线,违反 = L3 停机呈报) -🔴 **契约 1 · 零行为变更+公开面零变化**:两拆件族的**公开函数签名逐字保持**(宿主委托层承载);迁移体逐字一致(接收者化/参数化最小);断点 28 键的键名/缺省值/回退语义逐键冻结(对照表落实现报告);禁顺手改任何判定/缺省/顺序。 +🔴 **契约 1 · 零行为变更+公开面零变化**:两拆件族的**公开函数签名逐字保持**(宿主委托层承载);迁移体逐字一致(接收者化/参数化最小);断点 **27 顶层键**的键名/缺省值/回退策略逐键冻结(对照表落实现报告,读侧五类策略逐键归类登记);禁顺手改任何判定/缺省/顺序。 -🔴 **契约 2 · core 域纪律**:两新件 core 合规全过——零 UI 引用(S4)、零 await、随机只经注入的 RngServiceCore(S1/S2)、零表直读(数值经注入 db,S3/S5);头注 S10 形制。 +🔴 **契约 2 · core 域纪律**:两新件 core 合规全过——零 UI 引用(S4)、零 await、随机只经注入参数面(S1/S2——`_feat_ticket_consider(rg: RandomNumberGenerator)` 现形态 :772 随迁不改)、零表直读(数值经注入 db,S3/S5);头注 S10 形制+S13 基线零新增。 -🔴 **契约 3 · 断点专项回归**:`breakpoint_resume_test` 全绿+新增缺键旧档回退断言一条(判据=A3 缺省值表);五处快照时点集(A4)零增减。 +🔴 **契约 3 · 断点专项回归**:`breakpoint_resume_test` 全绿+iter36 wc2 续玩断言全程绿+新增「单源键集==写侧键集」断言一条(wr2);五时点集(A4)零增减零迁移。 -🔴 **契约 4 · 等价三证**(同 R1/R2 口径)+接线变异至少一条。 +🔴 **契约 4 · 等价三证**(§1 完成定义 2)+撤销证明至少两条(T3——P0 令形态)。 -🔴 **契约 5 · 范围收口**:只拆两族+单源化;`_settle`/`_start_current_level`/节点推进等其余面不动;`_place_variants` 搬迁(审计 §三附带小件)**不在本卡**(其属 battle_orchestrator 面,未立项)。 +🔴 **契约 5 · 范围收口**:只拆两族+单源化+**一条必改接线行**——`adventure_runner.gd:883-884` `_runner.set_shop_pool(_curio_deck, _consume_pool_purchase, _feat_ticket_consider, _curio_cap_ok)` 四标识符全在迁出面,该行随拆件改引(经宿主委托/件成员取值,参数序不变);除此与 `_settle`/`_start_current_level`/节点推进等其余面不动;`_place_variants` 搬迁(审计 §三附带小件,battle_orchestrator 面)不在本卡。 ## 5. 范围边界 -**做**:r3-1~r3-3+断点回退断言一条+等价三证+接线变异+产出物。 +**做**:r3-1~r3-3+断点键集断言+等价三证+撤销证明+产出物。 **不做**:battle_orchestrator 的段类再拆与 `_place_variants` 搬迁(未立项,留审计在册);present 层三控制器写调用归属(条目④裁点);R1/R2 面;卡①缺陷面。 @@ -73,8 +76,8 @@ | 文档 | 关联点 | 同步义务 | |---|---|---| -| [architecture](../design/engineering/architecture/architecture.md) 核心层/功能层模块归属表 | 两新 core 件登记(CurioDeck/ShopSession 归属行)+断点单源件(若独立成件)——与条目④「模块归属对齐」并批落文 | 反哺点 · 列清单(①:登记行草案,落文归④批统一裁决) | -| [存档序列化](../design/gdd/systems/表现与支撑/存档序列化.md) | 断点键集零变化——单源化不改契约,该文档陈述不变(T0 核对其是否逐键列清单,列则注记单源载体址) | 反哺点 · 列清单(②,预期零改动注记) | +| [architecture](../design/engineering/architecture/architecture.md) 核心层/功能层模块归属表 | 两新 core 件登记(CurioDeck/ShopSession 归属行)——与条目④「模块归属对齐」并批落文 | 反哺点 · 列清单(①:登记行草案,落文归④批统一裁决) | +| [存档序列化](../design/gdd/systems/表现与支撑/存档序列化.md) | 断点键集零变化——单源化不改契约;T0 核其是否逐键列清单(列则注记单源载体址) | 反哺点 · 列清单(②,预期零改动注记) | | [秘宝](../design/gdd/systems/跨局循环/秘宝.md)(若记令牌池结构)/商店相关 GDD | 结构载体址变化、机制语义零变化(T0 核) | 反哺点 · 列清单(③,预期载体址注记) | | `待办清单.md`/`roadmap.md` | 条目拆分注记与迭代行编入笔 | 反哺点 · 列清单(④⑤) | @@ -84,83 +87,85 @@ | 文件 | 职责 | 行为改动 | |---|---|---| -| `game/core/adventure_runner.gd` | 令牌池族拆出+委托层+断点写侧改单源驱动(复用既有·修改) | 非行为改动 → wr1 | +| `game/core/adventure_runner.gd` | 池与判定面拆出+委托层+断点写侧改单源驱动(复用既有·修改) | 非行为改动 → wr1 | | `game/core/level_runner.gd` | 商店族拆出+委托层(复用既有·修改) | 非行为改动 → wr1 | | `game/core/curio_deck.gd` | **新增**:令牌池件(新增·新文件) | 非行为改动 → wr1 | -| `game/core/shop_session.gd` | **新增**:商店子系统件(新增·新文件) | 非行为改动 → wr1 | -| 断点字段单源(`adventure_runner.gd` 内 const 或独立件,T0 定——倾向 const 随宿主) | 28 键登记单源(新增·常量/件) | 非行为改动 → wr1 | -| `game/tests/unit/core/breakpoint_resume_test.gd` | 缺键回退断言一条(复用既有·增断言) | 断言面 → wr2 | +| `game/core/shop_session.gd` | **新增**:商店件(新增·新文件) | 非行为改动 → wr1 | +| 断点字段单源(adventure_runner 内 `const BREAKPOINT_FIELDS`——§11 定值) | 27 键登记单源+写/读派生(新增·常量) | 非行为改动 → wr1 | +| `game/tests/unit/core/breakpoint_resume_test.gd` | 键集断言一条(复用既有·增断言) | 断言面 → wr2 | | 外部直引点(A5 清单) | 零改动预期(公开签名不变)——T0 核 | — | ### 接口块 -- `curio_deck.gd`:`extends RefCounted`;`_init(db: ConfigDb)`;持令牌多重集与三凭证计数;方法签名=原 AdventureRunner 私有函数去下划线同形(`build/pick/find_token/pool_stock/consume_purchase/stock_snapshot/draw_candidates/cap_ok/feat_ticket_consider/redeem_feat_ticket`…全清单=r3-1 函数表);宿主记账经回调注入(`_init` 追加 `ledger_write: Callable` 形态 L1)。 -- `shop_session.gd`:`extends RefCounted`;`_init(db: ConfigDb)`;`set_pool(deck_ref: Array, consume: Callable, ticket: Callable, cap: Callable)`(沿用 :823 四参面);方法=r3-2 函数表同形。 -- 断点单源:`const BREAKPOINT_FIELDS: Dictionary`(键→{"default": Variant, "deep": bool})+写侧取值器表/读侧回退表两派生函数(同文件或独立件,T0 定)。 -- 最窄闸:`breakpoint_resume_test`/`level_shop_economy_test`/`curio_refresh_paid_test`/`pool_case_d_test` 单件直跑;系统测试 `python tools/run_system_test.py`。 +- `curio_deck.gd`:`extends RefCounted`;`_init(db: ConfigDb)`;持令牌多重集+`_curio_taken`+凭证三计数;方法=迁出清单去下划线同形(`build/token_identity/find_token/pool_stock/consume_pool_purchase/stock_snapshot/consume_deck_token/draw_candidates/cap_ok/feat_ticket_consider/reset`);`feat_ticket_consider(rg: RandomNumberGenerator) -> bool` 形态随迁不改;宿主记账经回调注入(形态 L1)。 +- `shop_session.gd`:`extends RefCounted`;`_init(db: ConfigDb)`;`set_pool(deck_ref: Array, consume_handler: Callable, ticket_consider: Callable = Callable(), cap_check: Callable = Callable())`(与 :823 逐字对齐含缺省值);方法=商店 21 函数清单同形(`spend_gp` 随迁、出账经回调落宿主 `_gain_wallet`)。 +- 断点单源:`const BREAKPOINT_FIELDS: Dictionary`(键→{写侧取值键路径+读侧策略标签〔plain/keep_on_null/dual_merge/clamp/params_fallback/token_migration 六类〕})+写侧拼装/读侧回退两派生段。 +- 最窄闸:`breakpoint_resume_test`/`level_shop_economy_test`/`curio_refresh_paid_test`/`pool_case_d_test` 单件直跑+`tools/error_scan.py` 判红口径;系统测试 `python tools/run_system_test.py`;探针 `ui_click_probe`(iter36 wc2 断言)。 ### 落位与可复用性预检 -- **`curio_deck.gd`**——复用面:为什么不能复用既有件:全库令牌池逻辑唯一宿主即 adventure_runner 私有族(grep 实查),无第二实现;为什么不留在宿主:审计指认自成一体+1049 行超线。唯一面:令牌多重集与凭证计数唯一持有者(断点 `bonus_deck`/`bonus_taken`/`feat_ticket_*` 四键的数据源单点)。分层:core 件零引擎依赖;db 注入;随机经注入 rng(draw_candidates 的 rg 参数面沿用现状 :772)。 -- **`shop_session.gd`**——复用面:`set_shop_pool` 既有 Callable 注入面即拆件接口的现成形态(零新造协议);无第二商店实现。唯一面:货架/定价/购买/刷新唯一宿主(断点 `shop_shelf`/`shop_visit_buys` 数据源)。分层:core 件;钱包原语留宿主(账本单点)。 -- **断点单源 const**——复用面:为什么不独立成件:写侧取值器需要宿主成员闭包(28 键里 20+ 键取宿主态),独立件要把宿主全量开洞——const 随宿主+两派生函数最小;备选「独立 schema 件」淘汰依据=开洞面>收益。唯一面:键登记唯一处(三处消费全派生)。 +- **`curio_deck.gd`**——复用面:全库令牌池逻辑唯一宿主即 adventure_runner 私有族(grep 实查),无第二实现;为什么不留在宿主:审计指认自成一体+1049 行超线。唯一面:令牌多重集与凭证计数唯一持有者(断点 `bonus_deck`/`bonus_taken`/`feat_ticket_pity`/`feat_ticket_sold` 数据源单点)。分层:core 件零引擎依赖;db 注入;随机经注入 rg 参数面(现状形态)。 +- **`shop_session.gd`**——复用面:`set_shop_pool` 既有 Callable 注入面即拆件接口的现成形态(零新造协议);无第二商店实现。唯一面:货架/定价/购买/刷新唯一宿主(断点 `shop_shelf`/`shop_visit_buys` 数据源)。分层:core 件;钱包原语留宿主(账本单点,`spend_gp` 经回调)。 +- **断点单源 const 随宿主**——复用面:为什么不上独立件:27 键多数取宿主态(20+ 键取宿主成员/嵌套),独立件要把宿主全量开洞——const 随宿主+两派生段最小;备选「独立 schema 件」淘汰依据=开洞面>收益。唯一面:键登记唯一处(写侧+两读侧三消费全派生)。 - **零新增逻辑**:全部为搬运+登记单源化。 ### T0 事实坐实(≈0.25d) -- [ ] 复核 A1-A6(重点:A2 spend_gp 去留判定;A3 第三处枚举位精确定位+28 键缺省表逐键摘录;A5 外部直引清单)+两拆件族的宿主耦合面边界确认。可核查结果:边界判定与缺省表进实现报告素材。 -- [ ] 改前读数(行数、断点域/商店域套件通过数)。可核查结果:基线表在案。 +- [ ] 复核 A1-A6(重点:A3 27 键缺省/策略表逐键摘录;A5 外部直引清单;r3-1 边界函数逐一确认归属——尤其 `pick_curio`/`skip_empty_curio` 停点面归属复核)。可核查结果:边界判定表+27 键策略表进实现报告素材。 +- [ ] 改前读数(行数、断点/商店/令牌域套件通过数、ui_click_probe iter36 wc2 段绿读数)。可核查结果:基线表在案。 ### T1 商店拆件+断点单源(≈0.75–1d) -- [ ] 实装 r3-2(shop_session 拆出+委托层)+r3-3(单源 const+三处改派生)+断点回退断言。可核查结果:level_runner ≤800 行;28 键对照表逐键一致;断点域套件绿。 +- [ ] 实装 r3-2(shop_session 拆出+委托层)+r3-3(单源 const+写侧/两读侧改派生)+键集断言(wr2)。可核查结果:level_runner ≈780 读数记录;27 键对照表逐键一致;断点域套件+iter36 wc2 断言绿。 - [ ] 验收步骤:全套闸按域选档跑一次全绿。 ### T2 令牌池拆件(≈0.75d) -- [ ] 实装 r3-1(curio_deck 拆出+委托层+停点流程留宿主边界落地)。可核查结果:adventure_runner ≤650 行;逐字迁移核对表逐函数落位;令牌/商店域全部既有套件绿。 +- [ ] 实装 r3-1(curio_deck 拆出+委托层+停点面留宿主边界落地)。可核查结果:adventure_runner ≈850±10 读数记录;逐字迁移核对表逐函数落位;令牌/商店域全部既有套件绿。 - [ ] 验收步骤:全套闸全绿+改前改后读数对拍。 -### T3 接线变异+产出物落位卡(≈0.25d,末卡) +### T3 撤销证明+产出物落位卡(≈0.25d,末卡) -- [ ] 接线变异一条:临时断开宿主对 curio_deck 某委托(如 `pick_curio` 错指)→ 对应令牌域断言红 → 还原复绿;断点单源变异一条:单源临时改一键缺省 → 回退断言红 → 还原。记录进实现报告。 -- [ ] 写齐三份产出物(实现报告含两核对表+行数读数+28 键对照表+实机目检总清单〔商店购买/刷新/三选一/续玩断点抽查〕/代拍板追认单/反哺点)。 -- [ ] 合并前置:独立验收审计(同卡①口径)逐行「通过」。 +- [ ] 撤销证明两条(P0 令形态——只回退本批 hunk):①回退 shop_session 承接件任一函数 hunk(如 `pool_price` 承接体)→ 宿主委托/消费面引用未定义符号 → 套件直跑经 `tools/error_scan.py` 扫出 SCRIPT ERROR 红 → 还原复绿;②回退单源 const hunk → 键集断言直跑 error_scan 红(常量未定义)→ 还原复绿。记录进实现报告。 +- [ ] 写齐三份产出物(实现报告含两核对表+行数读数+27 键对照表+实机目检总清单〔商店购买/刷新/三选一/续玩断点抽查〕/代拍板追认单/反哺点)。 +- [ ] 合并前置:独立验收审计(同卡①口径——抽查重点=27 键对照表与逐字迁移核对表)逐行「通过」。 -**估时合计 ≈2–2.5d**。编排注记:前置卡①;与 R1/R2 可同迭代分波;断点面重(回退断言+五时点集)。 +**估时合计 ≈2–2.5d**。编排注记:前置卡①;与 R1/R2 可同迭代分波;断点面重(键集断言+五时点+iter36 wc2 回归)。 ## 8. 验证闸 ### 改动—验收对照表 -| 需求点 | 改动 | 验收测试(尾缀) | 层级 | 真实入口 | 变异/撤销证明 | +| 需求点 | 改动 | 验收测试(尾缀) | 层级 | 真实入口 | 撤销证明 | |---|---|---|---|---|---| -| wr1 三单元等价 | 两 runner 拆件+断点单源 | 全套闸绿+两核对表+28 键对照表〔wr1〕 | 集成 | 断点/商店/令牌域真实套件+系统测试 | 接线变异两条(T3);等价三证替代逐单元撤销(等价重构申报) | -| wr2 断点回退断言 | breakpoint_resume_test 增一条 | 缺键旧档回退断言〔wr2〕 | 单元 | 续玩真实读取路径(resume_adventure) | 单源改缺省 → 断言红(T3 变异②) | -| wr3 新件合规 | 两新件+单源 | S1-S5/S9/S10/S11 全零命中〔wr3〕 | 静态扫描 | 闸真实跑批 | 回退任一合规面 → 对应闸红 | +| wr1 三单元等价 | 两 runner 拆件+断点单源 | 全套闸绿+两核对表+27 键对照表〔wr1〕 | 集成 | 断点/商店/令牌域真实套件+系统测试+ui_click_probe(iter36 wc2) | 撤销证明两条(T3);等价三证替代逐单元撤销(等价重构申报) | +| wr2 断点键集断言 | breakpoint_resume_test 增一条 | 单源键集==写侧字典键集〔wr2〕 | 单元 | `_snapshot_breakpoint` 真实拼装路径 | 回退单源 const hunk → error_scan 红(T3②) | +| wr3 新件合规 | 两新件+单源 | S1-S5/S9/S10/S11/S13 全零命中〔wr3〕 | 静态扫描 | 闸真实跑批 | 回退任一合规面 → 对应闸红 | | wr4 产出物 | T3 三份 | 件核对〔wr4〕 | — | — | 缺项红 | -**测试削弱申报**:零(既有断言零改动;增断言一条)。**独立验收审计**:同卡① §8.3 口径(抽查重点=28 键对照表与逐字迁移核对表)。 +**测试削弱申报**:零(既有断言零改动;增断言一条)。**独立验收审计**:同卡① §8.3 口径。 ## 9. 异常分级 -- **L1(自救)**:两新件命名;委托层薄厚;单源 const 形态;spend_gp 去留(判据=账本原语单点原则)。 -- **L2(记录继续)**:A5 直引清单个别适配;回调注入面参数化细节。 -- **L3(停机呈报)**:迁移体无法逐字等价(耦合面比 A1 判定宽——判离指认失真回呈);断点对照表任一键不一致;任一断点/商店/令牌域套件非本批存量红;行数目标达不成(呈报,禁自扩);单源化需动 save_manager 结构(超 r3-3 范围)。 +- **L1(自救)**:两新件命名;委托层薄厚;单源 const 形态与策略标签命名;宿主记账回调具体形态。 +- **L2(记录继续)**:A5 直引清单个别适配;行数读数与预期的正常偏差。 +- **L3(停机呈报)**:迁移体无法逐字等价(耦合面比 A1/A2 判定宽——判离指认失真回呈);断点对照表任一键不一致;任一断点/商店/令牌域套件或 iter36 wc2 断言非本批存量红;单源化需动 save_manager 结构(超 r3-3 范围);r3-1 边界函数在实装中被迫跨侧(停点面与池面无法分离)。 ## 10. 代拍板白名单 1. 两新件命名与去下划线取舍(签名语义不变前提)。 2. 宿主记账回调的具体形态。 -3. spend_gp 去留(倾向随件迁)。 +3. `spend_gp` 随迁的回调落账写法。 4. 提交切分与 worktree 分支命名。 ## 11. 待裁点 -**零待裁点,开工门=U0。** 两处灰色地带推导定值(用户可否决,随 T3 反哺点呈报):①断点单源落**宿主内 const** 而非独立件——依据=28 键多数取宿主态、独立件开洞面大(预检节);②停点编排留宿主、只拆「池与判定」——依据=`_curio_pending`/`_curio_result` 停点态与断点时点集(A4)强耦合宿主流程,全拆=行为面扩大违零变更契约。备选淘汰依据各见预检/契约。 +**零待裁点,开工门=U0。** 三处灰色地带推导定值(呈报可否决,随 T3 反哺点):①断点单源落**宿主内 const** 而非独立件——依据=27 键多数取宿主态、独立件开洞面大(预检节);②**拆池不拆停点**的边界(refresh 族/兑付推进族留宿主)——依据=停点态与断点五时点强耦合宿主流程,全拆=行为面扩大违零变更契约(grilling R3-A1 订正 v1.0 全族迁移方案);③`spend_gp` 随商店件迁、经回调落宿主账本——依据=它只服务商店扣款而账本原语单点在宿主。备选淘汰依据各见预检/契约。 ## 12. 自审六查与 grilling 复核记录 -**自审六查(2026-10-24 写卡会话)**:①规格覆盖——r3-1~r3-3→T1/T2、断言/合规/变异/产出物→T1/T3,指到 wr1–wr4;②步骤扫描——一步一动作一可核查结果;③类型一致性——接口块与 A1-A6 实查一致(T0 判定点均附判定依据非裸 TBD);④审查焦点——补挂:断点 28 键对照表(契约 1/3)、缺键回退断言(wr2)、A6 交点(shop_bp_* 随迁不改断点取数)、五时点集冻结(契约 3);⑤篇幅比例——零实现体;⑥落位预检——两新件不能复用的理由、单源落宿主的理由、账本留宿主的边界均已答。 +**自审六查(2026-10-24 写卡会话)**:①规格覆盖——r3-1~r3-3→T1/T2、断言/合规/撤销/产出物→T1/T3,指到 wr1–wr4;②步骤扫描——一步一动作一可核查结果;③类型一致性——接口块与 A1-A6 实查一致(v1.1 边界重划后逐函数归属两侧清单化);④审查焦点——断点 27 键对照表(契约 1/3)、键集断言(wr2)、五时点全留宿主(契约 3)、A6 交点、iter36 wc2 回归纳入;⑤篇幅比例——零实现体;⑥落位预检——两新件唯一性、单源随宿主、账本留宿主边界均已答。 -**grilling 复核记录**:v1.0 成文后独立子代理对抗复核——记录见本节(复核后补写)。 +**grilling 第一轮复核记录(2026-10-25,独立子代理对抗复核)**:判回炉两阻断——R3-A1 r3-1 清单圈入 refresh 族/兑付面与「拆池不拆停点」边界直接互斥(断点时点 :634/:803 住在 refresh/兑付函数体内,随迁即扰动五时点;行数账两头堵);R3-A2 T3 两条变异违 2026-10-24 P0 令。随同五应修(F1 断点实为 27 顶层键非 28;F2 读侧回退语义远超 {default,deep} 双字段——五类策略实语义;F3 读侧漏 `_start_current_level` 四键二次消费;F4 save 侧零键登记、「三处」论断不成立;F5 iter36 wc2 断点断言未纳入+`_consume_deck_token` 漏迁+两函数归属未交代)+两建议(A2 区间收窄;set_pool 缺省值对齐)。v1.1 全部折入:r3-1 边界重划(迁出/留宿主两侧函数清单化、五时点全留宿主、`_consume_deck_token` 补入、`_feat_payload_keys`/`_apply_curio_pick` 归属留宿主)、27 键订正、读侧两消费位+五类策略登记、save 侧空派生订正(§12 回呈审计)、证明改撤销形态两条、iter36 wc2 纳入 T0 基线与回归面、区间收窄为函数清单、set_pool 逐字对齐。复核结论:两阻断闭合、五应修落位(v1.1)。 + +**grilling 第二轮复核记录(2026-10-25,同代理续核)**:总判**通过(附应修)**——A1 边界重划真闭合(两侧清单逐项对账无重叠无遗漏、五时点全留宿主实锤)、A2 撤销证明合规、F1–F5 全落。新发现两应修:①行数读数 710–730 系第一轮旧口径未随边界扩面重算(按 v1.1 清单实算迁出 ≈211 行→收 ≈850±10);②契约 5「其余面不动」与 :883-884 接线行互斥(四标识符全在迁出面,不改该行无法编译)。v1.2 折入:读数改 ≈850±10、契约 5 增接线行例外并列入 r3-1 改动面、策略词表统一六类、feats_held 留驻一行明示。零待裁点成立,卡进可编排态。 diff --git a/待办清单.md b/待办清单.md index 60e6e493..6ca95f42 100644 --- a/待办清单.md +++ b/待办清单.md @@ -19,10 +19,10 @@ **现状**:审计报告=reports/审计-game代码结构审查-2026-10-24.md(2026-10-24,全目录只读审查,零测试执行、结论全部静态阅读)。缺陷证据(报告 §二 Critical 行为缺陷段+定点清单,含行号)九件:①core/damage_controller.gd:215 用 `==` 比较单位字典(Godot 4 语义=逐键内容比较)——内容全同双敌其一死亡误作废对方单据,应 `is_same()`;②presentation/views/standee_body.gd:172/188 蓄力意图档常量错配(GOLD_INK vs GOLD_DEEP)死代码,三档运动签名设计失效且无测试覆盖;③presentation/views/battle_end_overlay.gd:281-287 庆祝 tween set_loops 无限叠加泄漏(close 只隐藏不 kill);④批量模拟×两层调试并发互斥缺口(presentation/views/debug_overlay.gd:84+presentation/main.gd:712-715/1489+presentation/tune_sim_controller.gd:46-58——用户两击可并触发,演出扭曲+测量作废);⑤presentation/modal_stack.gd:23-29 未登记层/重复开层静默降级(违 fail-fast,当前调用面无违规者属埋雷);⑥core/minesweeper_rules.gd:8-9 两条核心信号零契约成文(违 code-conventions §2.1)+全库信号注释载体普遍 `#` 非 `##`;⑦明细行类型封闭枚举漂移(core 实发 13 类 vs battle_orchestrator.gd 头注 9 类);⑧core/level_runner.gd:895/779 玩法数值字面量(relic 基价 15.0、散折 0.8,自注 provisional);⑨presentation/views/battle_stage_view.gd:332-338 以 display_name 子串匹配解析受击目标(同名敌错位,应携带 enemy_id)。另有定点小件与结构重构候选(报告 §三):main.gd 1508 行可判离块 ~440 行/board_view.gd 1219 行瓦片算法+英雄精灵可拆/adventure_runner 令牌池子系统 ~500 行可拆 CurioDeck/level_runner 商店子系统 ~260 行可拆/断点 schema 三处重复登记可单点化——重构候选非缺陷,是否立项由写卡段呈报用户裁决。**2026-10-24 写卡会话收口**:用户裁五件重构候选全部立项(卡①缺陷修先行落地后重构再动);缺陷⑦明细行枚举漂移划归「架构与规范对齐批」条目(词表 13/15 归该批裁决,缺陷卡不碰头注);报告 §三「其余小件」(level_map 视图直读/BFS、main 死变量与 confirm 旁路、settle_batch 空判、row_pacer 常驻 flush、_fatal assert 剥离、rng_service early-return)未立项,留审计报告在册待后续点名。切卡输入=审计报告 §二/§三,四卡均零待裁点。 关联文档清单: -- 需求卡片 reports/需求卡片-game行为缺陷定点修批-2026-10-24.md(2026-10-24 v1.0,缺陷修主卡·迭代批,八件缺陷+定点小件七件,零待裁点) -- 需求卡片 reports/需求卡片-重构main判离批-2026-10-24.md(2026-10-24 v1.0,重构卡 R1·迭代批,零待裁点) -- 需求卡片 reports/需求卡片-重构boardview拆件批-2026-10-24.md(2026-10-24 v1.0,重构卡 R2·迭代批,零待裁点) -- 需求卡片 reports/需求卡片-重构runner拆件与断点schema单点批-2026-10-24.md(2026-10-24 v1.0,重构卡 R3·迭代批,零待裁点) +- 需求卡片 reports/需求卡片-game行为缺陷定点修批-2026-10-24.md(2026-10-24 v1.2(grilling 两轮复核通过),缺陷修主卡·迭代批,八件缺陷+定点小件七件,零待裁点) +- 需求卡片 reports/需求卡片-重构main判离批-2026-10-24.md(2026-10-24 v1.2(grilling 两轮复核通过),重构卡 R1·迭代批,零待裁点) +- 需求卡片 reports/需求卡片-重构boardview拆件批-2026-10-24.md(2026-10-24 v1.2(grilling 两轮复核通过),重构卡 R2·迭代批,零待裁点) +- 需求卡片 reports/需求卡片-重构runner拆件与断点schema单点批-2026-10-24.md(2026-10-24 v1.2(grilling 两轮复核通过),重构卡 R3·迭代批,零待裁点) **归属**:game/ 呈现层与 core 域(缺陷定点修,迭代批);结构重构候选另立批次由用户裁决。切卡输入=审计报告 §二/§三 @@ -33,7 +33,7 @@ **现状**:工程债证据=reports/审计-game代码结构审查-2026-10-24.md §二 C1(已独立复现):tools/audit_type_hints.py:29 的 FUNC_DECL 正则两洞——①无返回类型声明按 GDScript 语法必然以 `:` 结尾,正则要求 `)` 后只跟 `->`/注释/行尾,R2 目标形态 100% 失配(R2 从上线起恒零命中恒绿);②`^(\s*)func` 不认 `static ` 前缀,static 函数对 R2/R3 整体漏网。实证存量(闸当前退出码 0):core/level_runner.gd:632、core/attunement.gd:10、presentation/main.gd:565、presentation/views/hud_presenter.gd:10-11、core/reward_economy.gd:104/119/131/146、core/unit_container.gd:275(写卡会话路径订正:hud_presenter 实址 game/presentation/hud_presenter.gd,非 views/)。属架构文档测试域自警的「规则扫描面为空=恒绿」静默失效模式(零命中自检因 R1/R3 仍有命中能力未拦住)。 关联文档清单: -- 需求卡片 reports/需求卡片-S9类型闸正则修复批-2026-10-24.md(2026-10-24 v1.0,非迭代批,零待裁点;存量清单以开工时盘面清点,实证九址为已知下限) +- 需求卡片 reports/需求卡片-S9类型闸正则修复批-2026-10-24.md(2026-10-24 v1.2(grilling 两轮复核通过),非迭代批,零待裁点;存量清单以开工时盘面清点,实证九址为已知下限) **归属**:tools/ 静态扫描域(闸件批,非迭代批——gdstyle 引入批 2026-10-24 已按同款形态收口:先摸存量、闸改动配变异验证)