diff --git a/design/engineering/test-conventions.md b/design/engineering/test-conventions.md index 22133feb..a1975809 100644 --- a/design/engineering/test-conventions.md +++ b/design/engineering/test-conventions.md @@ -1,5 +1,6 @@ # 测试规范(Dungeon Sweeper) +> 现行为 v1.0(2026-11-09) > 约束范围:`game/probe/ 与 game/sim/`、`game/tests/` 与一切场景探针的编写与验收。 > 分工:测试**执行义务**(改完必须测什么)归 AGENTS.md「硬性红线·改完即测铁规」与 `process-conventions.md` §4;**跑什么闸、什么顺序**归 `tools/run_all_gates.sh`(脚本即清单,本文与 AGENTS.md 均不另列);本文管测试怎么写、怎么算合格。每件测试工具**是什么、判什么、怎么单独跑、什么时候适合单独用**——见 `game/tests/README.md`(测试工具手册),本文不重复工具介绍。 > 归属:随游戏逻辑写/改的测试=需求改动的一部分(随需求卡片同批落地);不伴随逻辑改动的纯测试维护=工程改动(不写卡,用户发令直改)。 @@ -34,7 +35,7 @@ 凡模态覆盖层,探针必须断言:打开后自身 visible 且遮挡物已隐藏(模态被遮挡 = 功能存在但不可达)。 -**UI 驱动断言须走真输入管线(2026-11-06 立)**:探针里「点按钮/点场景物件」类驱动断言,一律经引擎输入管线承载(合成 InputEvent 走 `push_input`,press+release 成对;合成滚轮同样必须 press+release 成对——只发 press 会把鼠标焦点钉死在按下点控件上,后续点击全部失效);信号直发(`pressed.emit()` 等)绕过命中测试,保不了「玩家点击可达」,只许用于真输入到不了的面并当场标〔接线断言〕(现役例:置灰态穿透钉处理器兜底)。折叠区控件先以真输入滚轮滚入可视区再点。每个动线断言钉「落点」判定(点了之后到哪个屏/哪层可见),防驱动中断后的空转假绿。真输入命中控件时自动登记控件覆盖(探针共用面登记件落 `.gates/` 观测产物),覆盖面生长不靠人记。 +**UI 驱动断言两段式:先接线、后真输入(2026-11-06 立;2026-11-09 用户裁两段式)**:探针里「点按钮/点场景物件」类驱动断言按先后两段执行——**第一段接线断言**:信号直发(`pressed.emit()` 等)验证信号接线与处理器逻辑,快速失败(接线不通即红,不必等真输入段定位);**第二段真输入断言**:经引擎输入管线承载(合成 InputEvent 走 `push_input`,press+release 成对;合成滚轮同样必须 press+release 成对——只发 press 会把鼠标焦点钉死在按下点控件上,后续点击全部失效),验证玩家点击可达。真输入绕过不得——信号直发绕过命中测试,保不了「玩家点击可达」;真实入口只认第二段(§8.3 口径不变),第一段不充当能力行的真实入口。真输入到不了的面(现役例:置灰态穿透钉处理器兜底)止于第一段并当场标〔接线断言〕。折叠区控件先以真输入滚轮滚入可视区再点。每个动线断言钉「落点」判定(点了之后到哪个屏/哪层可见),防驱动中断后的空转假绿。真输入命中控件时自动登记控件覆盖(探针共用面登记件落 `.gates/` 观测产物),覆盖面生长不靠人记。 ## 3. 缺陷修复必须沉淀回归断言 @@ -117,7 +118,9 @@ **判据出处锚(2026-11-05 立;2026-11-09 用户裁内容化改版——行号形态废止,内容节锚为唯一形态)**:对照表「需求点」列每行必须带**判据出处锚**——该行验收判据所依据的现行文档句子,格式「`<文档相对路径>「节名」<行关键词>`」。现行文档=`design/` 全域现行文档(含 `ux/` 交互规格与 art-bible 的判据行);已退役的需求卡片不是现行文档,不得充当判据出处。节名=判据句所在节的标题词(节名首段「·」前须命中目标文档标题行);行关键词=判据句上的无空白子串(须落在该节块内)。锚指向内容不指向行号——文档增删行不牵动锚与测试代码,只有判据句内容真被改动才使锚失配;失配(节名不在档/关键词不命中)=红,改动该句的文档批同批改锚。作用=断言预期值从规格句抄出,不从实现反推:实现行为与规格句冲突时断言红;规格缺席的行写不出锚,即停卡退回写卡段(那是需求澄清缺口,不是测试缺口)。机检=`tools/pipeline_gate.py` 判据 C5(内容锚形态唯一+节名在档+关键词命中节内,核验口径归 `tools/anchor_util.py` 共用件;行号形态出现即红)+`tools/capability_audit.py` 链式锚检查(断言→套件→能力行→系统文档,见 §8.9)。 -**测试函数的判据出处注记(2026-11-06 立;2026-11-09 内容化改版——内容节锚唯一形态)**:`game/tests/**` 与 `game/probe/**` 内每个**验证函数**(函数体含 `check(`/`check_quiet(`/`_problems.append(`/`push_error(` 判定调用的函数——定义行与 `_check(` 前缀不作判定计)必须带至少一条**判据出处注记**,格式「`# 判据出处: 「节名」<行关键词> <判据一句>`」——指针在前、判据摘要句在后;节名与行关键词口径同上(卡片判据锚同款,`game/sim/` 测量面实现件无标题结构,节名与关键词按文件内子串命中),断言预期值的出处随断言走:断言红时读注记即达出处文档句,零查表。指针空间=`design/` 全域现行文档(行为测试锚 owner 系统文档「验收标准」句或 `ux/` 规格句;惯例类测试〔封装扫描、判定通道纪律、驱动契约〕锚规约条款行;测量面驱动契约锚 `game/sim/` 实现件文件头注——规范句在哪锚哪,2026-11-09 架构收敛批立);`game/sim/` 不进扫描面(测量面直构惯例)。与链式锚的分工:链式锚(断言→套件→能力行→系统文档)不变、属义务清单层;本注记属执行证据层、写在断言文件内,非独立账本(§8.9 法则 4 不变)。写新测试函数时当场挂注记;判据句被改动使关键词失配时,改动该句的文档批同批改锚——失配即红。局限如实声明:注记核验到「关键词命中节内」粒度,判据句被改写而关键词仍为其子串时语义漂移机检抓不到,由复核门实读兜(与卡片判据 C5 同限)。机检=`tools/capability_audit.py` 判据出处注记道(覆盖检查+内容锚核验,行号形态出现即红;扫描面零文件自检红)。规格缺席写不出锚=发现规格缺口:记发现不造锚、收尾呈报,禁锚到非现行文档凑数。 +**测试函数的判据出处注记(2026-11-06 立;2026-11-09 内容化改版——内容节锚唯一形态)**:`game/tests/**` 与 `game/probe/**` 内每个**验证函数**(函数体含 `check(`/`check_quiet(`/`_problems.append(`/`push_error(` 判定调用的函数——定义行与 `_check(` 前缀不作判定计)必须带至少一条**判据出处注记**,格式「`# 判据出处: 「节名」<行关键词> <判据一句>`」——指针在前、判据摘要句在后;节名与行关键词口径同上(卡片判据锚同款,`game/sim/` 测量面实现件无标题结构,节名与关键词按文件内子串命中),断言预期值的出处随断言走:断言红时读注记即达出处文档句,零查表。指针空间=`design/` 全域现行文档(行为测试锚 owner 系统文档「验收标准」句或 `ux/` 规格句;惯例类测试〔封装扫描、判定通道纪律、驱动契约〕锚规约条款行;测量面驱动契约锚 `game/sim/` 实现件文件头注或本节「批量模拟测量语义」句——规范句在哪锚哪,2026-11-09 架构收敛批立);`game/sim/` 不进扫描面(测量面直构惯例)。与链式锚的分工:链式锚(断言→套件→能力行→系统文档)不变、属义务清单层;本注记属执行证据层、写在断言文件内,非独立账本(§8.9 法则 4 不变)。写新测试函数时当场挂注记;判据句被改动使关键词失配时,改动该句的文档批同批改锚——失配即红。局限如实声明:注记核验到「关键词命中节内」粒度,判据句被改写而关键词仍为其子串时语义漂移机检抓不到,由复核门实读兜(与卡片判据 C5 同限)。机检=`tools/capability_audit.py` 判据出处注记道(覆盖检查+内容锚核验,行号形态出现即红;扫描面零文件自检红)。规格缺席写不出锚=发现规格缺口:记发现不造锚、收尾呈报,禁锚到非现行文档凑数。 + +**批量模拟测量语义(测量面驱动契约,2026-11-09 用户裁落文)**:调试浮窗批量模拟(tune_sim,呈现层调参测量件)与 headless 扫描同口径(同款自动策略驱动);逐帧步进每局恰占一帧——第 0 局在调用点同步段执行,第 i 局(i≥1)在第 i 帧信号发射点执行,收尾恒在第 n 帧发射点;n=0 退化路径为调用点同步收尾零帧;进度逐局更新,报告注入与运行态复位在整批收尾之后。双实现对拍套件(产品码帧步进形态 vs 旧 await 形态夹具)以本句为判据出处。 **验收档申报(2026-11-04 立,自 2026-11-05 起对文件名日期不早于该日的需求卡片生效;旧卡不回头改)**:每张需求卡片在头部信息区(与设计事实源声明同区)申报一个验收档,三档:高/中/低。判据=失败代价单维——这条改动做错了,后果随存档或结算传播的(存档写读与迁移、RNG 流、战斗结算公式与乘区、经济入账、数值表结构校验)=高;后果玩家可见但不损持久状态的(常规玩法逻辑、门控、交互逻辑、呈现数据面)=中;后果即看即知且无状态残留的(文案、纯呈现样式、布局微调)=低。一张卡触多档按最高档申报;申报由写卡段落笔,用户批卡(U0)时确认或改判。档位只调节 §8.7 审计深度——闸机与 CI 的域划分、选闸算法、全量强制档一概不因档位变化,真实入口、判据绑定面、禁削弱等验收闭合判据全部照旧。未申报档位的卡一律按高档全量审计。机检=`tools/pipeline_gate.py` 判据 C4:卡内须含「验收档:高/中/低」申报行。 diff --git a/design/ux/battle.md b/design/ux/battle.md index 50c4a432..c160342c 100644 --- a/design/ux/battle.md +++ b/design/ux/battle.md @@ -277,6 +277,8 @@ | 全屏 | 胜利/失败 overlay | 模态 | 金蜡封/暮蓝收印 + 判定行(无明细回看入口——回看归「生涯」) | 继续/下一节点 | 已实装 | | 调试 | 调试浮窗 | 调试面板 | 种子/数值调整/批量模拟/两层调试入口(发布态恒隐,无 UI 开启口;调试开关门控口径见「调试变体」行;调参面板已退役入调试浮窗) | 调试 | 调试浮窗 | +> **按钮组等宽纪律(2026-11-09 用户裁)**:同一直接父容器内 ≥2 个可见按钮,宽度必须相等(差 ≤1px)——组内等宽,结构探针 equal_width 审计按本句全站执行。现行例:AP 条停手钮与图例钮同横排容器,两钮宽度统一 64px。 + **布局决策 2 —(已删除,编号留空)**:编号留空,免布局决策 3/4 的既有交叉引用失锚。 **布局决策 3 — 移动路径预览 = 合法性指示**(排雷玩法×6⑤ 悬案裁决):悬停已开格时高亮 BFS 路径(小人蓝细线点迹),移动执行为 ≤150ms 短滑。 diff --git a/game/tests/README.md b/game/tests/README.md index 25bfa760..8ed476f0 100644 --- a/game/tests/README.md +++ b/game/tests/README.md @@ -193,6 +193,8 @@ tests/ | 停手钮真输入命中与停手收轮落效 | 行动经济 | ui_click_probe 使能窗真输入点击(AP 条停手钮经 `ProbeUiUtil.push_click()`)+journey_player 全线跑批(sim) | `ui_click_probe.gd:_stoptest_tick`(计划测试——需求卡片「QA harness 缺陷与覆盖遗漏收口批」2026-11-06 锚定) | | 停点链与控件级真输入命中 | HUD框架 | 探针与测试宿主真输入驱动(节点继续/三选一选卡·确认/弃图刷新确认/奖励刷新/地图候选矩形中心/调试浮窗钮,一律经 `ProbeUiUtil.push_click()`/`push_click_at()` 进 `push_input`) | `ui_click_probe.gd:_ready`(停点链段——计划测试,需求卡片「QA harness 缺陷与覆盖遗漏收口批」2026-11-06 锚定) | | 控件动线扩面真输入可达(图例关闭/节点继续/三选一与商店/秘宝架/树高档与先手/弃图链/地图放弃/Esc 设置/减动效开关) | HUD框架×各屏 | 合成 InputEvent 经 Viewport push_input 真点注入(`ProbeUiUtil.push_click_at()`;扩面十一段,高档钮经调试注钥使能) | `ui_click_probe.gd:_ready`(动线扩面段)(计划——需求卡片「QA覆盖余量收口批」2026-11-07 锚定) | +| 冒险簇选路两段式与战斗HUD实采样结构审计 | HUD框架×关卡画面 | 合成鼠标事件经 Viewport push_input 真点候选命中矩形中心(`ProbeUiUtil.push_click_at()`)→ `LevelMapScreen._submit_choice()` → `route_chosen` → 组合根回战斗屏;第一段 emit 接线断言快速失败、不充当真实入口 | `ui_struct_probe.gd:_adventure_wiring_stage`/`ui_struct_probe.gd:_adventure_real_stage`(计划——需求卡片「测试面四项收口批」2026-11-10 锚定) | +| 图例层两段式开合 | HUD框架 | AP 条图例钮 `ProbeUiUtil.push_click()` 真点开层 → 「关闭」钮真点收层(`find_button()` 寻钮);第一段 `pressed.emit()` 标〔接线断言〕 | `ui_struct_probe.gd:_legend_two_stage`(计划——需求卡片「测试面四项收口批」2026-11-10 锚定) | **旅程段七:数据配置与跨系统契约** diff --git a/reports/复核-测试面四项收口批-2026-11-10.md b/reports/复核-测试面四项收口批-2026-11-10.md new file mode 100644 index 00000000..2e6df84e --- /dev/null +++ b/reports/复核-测试面四项收口批-2026-11-10.md @@ -0,0 +1,27 @@ +# 复核报告——测试面四项收口批(2026-11-10) + +复核对象:reports/需求卡片-测试面四项收口批-2026-11-10.md +复核者:只读子代理(general-purpose,未参与卡片撰写);形态=对抗复核一轮,禁改文件、禁跑测试。 +工作区:D:/code/g-plan2-testface-closure(worktree,基点 0f686900)。 + +## 审点结论 + +1. 验收三问(V1–V5):真实入口均走第二段 push_click_at/push_click→_submit_choice→route_chosen→组合根,不绕改动点;判据绑定面绑被测特有提交面。两条观察:equal_width 腿 enable 态空转风险(自判,钉值腿兜底);V5 注记改动可观测面=capability_audit 内容锚核验(非行为改动,机检兜底成立)。 +2. F1–F13 实读对账:全部属实,零漂移。 +3. 预检 vs 结构图:新增文件零、新增函数三均落 ui_struct_probe.gd,不能复用理由与唯一落点在案。零发现。 +4. 预算:返回出口计数「两」与 T2 三返回不符(自判,改「三」);余数字核实。 +5. 拆分边界:三单元各有职责与单一变化原因,adventure 拆二/legend 自包含的不对称有据。零发现。 +6. 引擎 4.7.2 三查:push_input/InputEventMouseButton press+release/custom_minimum_size/Array.find/await 均有库内实证;push_click_at 成对不踩焦点钉死;钉值用 custom_minimum_size.x、等宽用 size.x 区分正确;探针非热路径。零发现。 +7. 契约可执行性:C-2 与 T1–T4 自洽;begin_session(true) queue_free 旧 run_scope 重开成立(main.gd:112-118/:295);真输入段 isolate_save 三参未显式钉(补写)。 +8. 能力表:README 新增两行与卡能力行格、T2 函数名逐字一致。零发现。 +9. 判据锚:三锚按 anchor_util 口径手工核全 PASS(节名命中标题行、关键词落节块内)。 + +## 发现清单(3 条 actionable) + +| 卡内位置 | 发现 | 去向 | 依据 | 处置 | +|---|---|---|---|---| +| §14 预算 | 「两返回出口」与 T2 三返回不符 | 自判 | 卡 T2 真点段三步 | 改「三返回出口」,已落卡 | +| T2 真输入段步骤 | isolate_save 三参未显式钉 | 补写 | ui_struct_probe.gd:219、ui_click_probe.gd:615 | 补确切调用 (main, tag, true, false, true),已落卡 | +| V2/V4 equal_width 腿 | 停手钮 disabled 时排除出组致该腿空转 | 自判 | ui_struct_probe.gd:710/:791-792 | 不改判据(钉值腿兜底);T4 报告步骤补 enable 态读数义务,已落卡 | + +无待裁、无退回上游。结论:卡片设计闭合、判据锚与能力表名实相符,复核通过。 \ No newline at end of file diff --git a/reports/需求卡片-测试面四项收口批-2026-11-10.md b/reports/需求卡片-测试面四项收口批-2026-11-10.md new file mode 100644 index 00000000..d33eef47 --- /dev/null +++ b/reports/需求卡片-测试面四项收口批-2026-11-10.md @@ -0,0 +1,204 @@ +# 需求卡片——测试面四项收口批 + +> 来源:待办清单「测试面真输入化批发现四项待裁(2026-11-06 登记,来源=批次移交)」条目(唯一事实源:design/engineering/test-conventions.md v1.0「2. 场景级探针标配」两段式句+「8.3 改动—验收对照表」批量模拟测量语义句+design/ux/battle.md「Component Inventory」按钮组等宽纪律句) +> 验收档:低(按钮宽度=纯呈现样式;探针与测试注记不进玩家持久状态——失败代价即看即知、无状态残留) +> 估时:0.75–1.5 个工作日(中值 1.125);超 1.5 日软盒预挂=T2 真输入选路落点不稳(输入锁/视口变换漂移)时停机呈报,不扩面自救 + +## 1. 目标与完成定义 + +收口测试面真输入化批移交的四项发现:① ui_struct_probe 冒险簇 emit 选路绕过视图置隐前提、battle_hud 结构审计空转假绿——改两段式(先接线断言快速失败、后真输入保玩家可达);② AP 条停手钮 64px/图例钮 56px 同容器宽度不等——统一 64px;③ 图例段 emit 开启(被①卡住的真输入承载)——改两段式;④ tune_sim_batch_parity 两处判据出处注记锚泛称——改锚到批量模拟测量语义句。 + +完成定义: +- V1–V5 验收行全部在真实跑批中执行并通过;代码域闸按改动域选档全绿。 +- 独立验收审计(低档)通过;reports/ 两份产出物落齐;能力表新增两行在场且名实相符。 +- 产品码改动仅限 ap_bar_view.gd:102 一处宽度值;选路/切屏/模态栈产品码零改动。 + +## 2. 设计事实源 + +- design/engineering/test-conventions.md v1.0「2. 场景级探针标配」两段式句:「UI 驱动断言两段式:先接线、后真输入……第一段接线断言……快速失败……第二段真输入断言……真实入口只认第二段……每个动线断言钉『落点』判定……防驱动中断后的空转假绿」(V1/V2/V3 判据)。 +- design/ux/battle.md「Component Inventory」按钮组等宽纪律句:「同一直接父容器内 ≥2 个可见按钮,宽度必须相等(差 ≤1px)……现行例:AP 条停手钮与图例钮同横排容器,两钮宽度统一 64px」(V4 判据)。 +- design/engineering/test-conventions.md v1.0「8.3 改动—验收对照表」批量模拟测量语义句:「逐帧步进每局恰占一帧……n=0 退化路径为调用点同步收尾零帧……双实现对拍套件……以本句为判据出处」(V5 改锚目标)。 +- design/gdd/systems/表现与支撑/HUD框架.md「提示与弹层:轻提示随起随消、重弹层排队进出」入栈出栈句(图例开合判据,沿用 ui_struct_probe.gd:248 现存注记锚)。 +- design/ux/level-map.md「UX Spec: 关卡画面」四项设计拍板(选路判据,沿用 ui_struct_probe.gd:218 现存注记锚)。 + +会话裁决沿革:用户 2026-11-09 裁——①③「两种都做、保持先后顺序:先接线断言快速失败,断言过了再真输入」;②「统一 64px、现在修」;④规格句落 test-conventions 测量面节;等宽句写入 battle.md。三句规格已随本 worktree 文档批定稿(test-conventions.md v1.0、battle.md 等宽句),实现批只消费不直改。 + +## 3. 现状事实(开工自行复核) + +- F1 emit 绕过置隐前提:game/probe/ui_struct_probe.gd:227 `route_chosen.emit(battle_id)` 直发;产品正路=game/presentation/views/level_map_screen.gd:458-465 `_submit_choice`(战斗/Boss 先 `visible = false` 再 emit);game/presentation/main_adventure_flow.gd:195-197 `on_route_chosen` 只在地图屏已隐时收栈回战斗屏(:209-211 `exit_level_screen` 置 `battle_root.visible = true`)→ emit 路径下 battle_root 恒隐,:229 battle_hud 审计空转采样(:227 注记实证在案)。 +- F2 全仓唯一剩 emit 图例段=ui_struct_probe.gd:249 `_btn_legend.pressed.emit()`(:249 注记「真点不可达……呈报待裁」);ui_click_probe.gd:1208-1236 图例已真输入(push_click 开+find_button「关闭」真点关+locks_input 读)。 +- F3 宽度现值:game/presentation/views/ap_bar_view.gd:62 停手钮 `Vector2(64, 0)`;:102 图例钮 `Vector2(56, 0)`;两钮同 row HBox(:65/:105 `row.add_child`)。确认弃图钮(:94)与弃图刷新钮(:110)min_w=0 豁免宽度基准且各在独立容器(_confirm_row/refresh_box),不属等宽组。 +- F4 equal_width 审计:ui_struct_probe.gd:5 头注纪律②;:781-812 同直接父容器 ≥2 可见按钮宽度差 >1px 红;:17 `WL = {}` 空豁免。 +- F5 注记现锚:game/tests/unit/presentation/tune_sim_batch_parity_test.gd:166/:199 两处「判据出处」锚 test-conventions「5. 测试函数怎么写——验收清单条目的落码规范」需求卡片(泛称,非测量语义判据句);五面对拍断言体(:173-195/:206 起)不改。 +- F6 重开冒险先例:game/probe/ui_click_probe.gd:615-619/988-992 `isolate_save` 新 tag+种子钉死+`_start_adventure_from_menu()`;game/presentation/main.gd:190-196 该函数无上下文守卫(探针直调中间态保留),调 `_start_adventure()`(:292 起,begin_session 重开会话)。 +- F7 选路真点先例:game/probe/ui_input_probe.gd:110-136 press+release 成对、抬杆沿提交;落点断言=地图屏隐∧`awaiting_choice()` 假。命中矩形读口=level_map_screen.gd:470-481 `candidate_rect(index) -> Rect2`(全局坐标、与 _candidate_at 同源、越界返回空 Rect2)。 +- F8 探针共用面签名:game/probe/probe_ui_util.gd:98 `isolate_save(main, tag, mark_first_done=false, with_settings=false, swap_save=true)`;:130 `push_click(main, ctrl)`;:134 `push_click_at(main, pos)`;:19 `find_button(root, needle, mode="prefix")`;:200 `scroll_button_into_view(main, view, btn)`。 +- F9 接线断言观测面:game/core/level_runner.gd:646-654 `pick_next_node`(AWAITING_CHOICE→RUNNING+_enter_node,候选外拒绝);:482 `awaiting_choice() -> bool` 读口。 +- F10 能力表:game/tests/README.md:163 调参测速批量模拟行在场(本批入口/用例名不变);无 battle_hud 结构审计与结构探针图例能力行(本批新增两行,写卡段已落)。 +- F11 gdstyle 基线:tools/gdstyle_baseline.txt 对 ui_struct_probe.gd/ap_bar_view.gd/tune_sim_batch_parity_test.gd 三件零登记键(grep 零命中;基线只登 core/presentation 存量超限键)。 +- F12 注记内容锚口径:test-conventions.md:121 注记条款(测量面驱动契约锚「批量模拟测量语义」句;行号形态出现即红;机检=tools/capability_audit.py)。 +- F13 探针规模:ui_struct_probe.gd 859 行、25 函数、1 成员变量(problems);冒险簇现内联 _ready :217-259。 + +## 4. 设计契约 + +- 🔴 C-1 两段式顺序不可倒:连接线断言在前(快速失败)、真输入在后;真实入口只认第二段,第一段不充当能力行真实入口(test-conventions「2. 场景级探针标配」两段式句)。触碰=L3 停机呈报。 +- 🔴 C-2 游戏行为零改动:本批产品码改动仅限 ap_bar_view.gd:102 宽度值;选路/切屏/模态栈产品码(level_map_screen/main_adventure_flow/main.gd)一行不改——探针问题修探针,不修产品。触碰=L3。 +- 🔴 C-3 禁削弱测试:现存断言族(battle_hud/status/legend 结构审计、standeefit、状态面板只读/零动效契约、parity 五面对拍)不删不改判据;equal_width 豁免册 WL 保持空;不放宽阈值。 +- 🔴 C-4 禁为机检文本保留无效成员(code-conventions §1.1 同款):机检键与卡片契约互斥时一律停卡呈报,禁自造第三条路。 +- 🔴 C-5 拆分边界纪律(判据权威=code-conventions §1.1 拆分判据):本卡拆出的每个私有函数须有可陈述职责与单一变化原因、须有集体身份;「过阈值」只作发现信号不作拆分动机;按纪律拆不出内聚单元=停卡呈报走豁免通道,禁硬拆凑绿。 + +## 5. 范围边界 + +做:ui_struct_probe 冒险簇两段式重写(含 battle_hud 实采样落点钉);图例段两段式重写;ap_bar_view 图例钮宽度 56→64;parity 两处注记改锚;能力表新增两行(写卡段动作,随卡已落)。 + +不做: +- 不改选路产品码时序(on_route_chosen/_submit_choice 的置隐先后是产品语义,探针绕过了它——修探针不修产品)。 +- 不动 ui_click_probe/ui_input_probe 既有真输入段(相邻面只跑回归确认)。 +- 不实装 battle.md 2026-11-07 侧栏改版定稿(停手左栏/图例右栏——代码未实装,属后续呈现改版批;本批只在现行横排布局下统一宽度)。 +- 不扩 equal_width 审计面(高度族/其他屏纪律不动);不改 tune_sim 产品码与对拍断言体。 + +## 6. 关联文档同步面 + +| 文档 | 关联点 | 同步义务 | +|---|---|---| +| design/engineering/test-conventions.md | §2 两段式句、§8.3 批量模拟测量语义句 | 无需同步——文档批已前置定稿(本 worktree),实现与规格句一致 | +| design/ux/battle.md | Component Inventory 等宽纪律句现行例(64px) | 无需同步——规格句已前置写入,与实现一致 | +| game/tests/README.md | 能力表新增两行(冒险簇两段式/图例两段式) | 写卡段已当场入表(本卡随附动作);实现批只核对名实相符,禁直改 | +| 待办清单.md | 四项条目状态与凭据 | 写卡段推进「已写卡」并登记卡路径+复核报告路径;实现入库后条目整条删除归批后收尾段 | + +本批实现不改任何设计文档陈述——反哺点清单预期零条(T4 仍产出文件并逐条对同步面声明落点)。 + +## 7. 文件结构图与任务卡 + +### 文件结构图 + +| 文件 | 职责 | 改动性质 | +|---|---|---| +| game/presentation/views/ap_bar_view.gd | 图例钮最小宽度 56→64(:102 单值) | 行为改动(呈现)→ V4 | +| game/probe/ui_struct_probe.gd | 冒险簇两段式+图例两段式重写;新增三私有函数(复用既有件 ProbeUiUtil,新增函数理由见预检节) | 非行为改动(探针测试面)→ V1/V2/V3 | +| game/tests/unit/presentation/tune_sim_batch_parity_test.gd | 两处判据出处注记改锚(:166/:199) | 非行为改动(注记)→ V5 | +| game/tests/README.md | 能力表新增两行 | 非行为改动(写卡段动作,随卡完成) | + +### T0 基线读数(0.1–0.2 日) + +取用:无。产出:基线读数(T1/T2 对拍用)。 + +- [ ] 逐条复核 F1–F13(file:line 实查);漂移即停卡呈报。 +- [ ] 孤立直跑结构探针取基线:仓库根跑 `D:\code\godot\Godot_v4.7.2-stable_win64_console.exe --headless --path game res://probe/ui_struct_probe.tscn`,记录退出码与 problems 输出(预期零红;battle_hud 审计空转为在册现状)。 + +### T1 宽度统一(V4;0.15–0.3 日) + +取用:无。产出:图例钮宽度 64(T2 equal_width 实采样依赖)。 + +- [ ] 改 ap_bar_view.gd:102 `Vector2(56, 0)` → `Vector2(64, 0)`。 +- [ ] 跑渲染闸 `bash tools/render_gate.sh game`:battle 截图 golden 若红,新基线逐张呈用户审核(登记不阻塞),实现报告记录换代读数;零红则记录读数。 +- [ ] 孤立直跑 ui_struct_probe.tscn 确认零新增红(此时审计仍空转、equal_width 未触发,属预期中间态)。 + +### T2 冒险簇与图例两段式(V1/V2/V3;0.3–0.6 日) + +取用:ProbeUiUtil 既有面(F8 签名逐字);`LevelMapScreen.candidate_rect(index: int) -> Rect2`;`LevelRunner.awaiting_choice() -> bool`;`main._start_adventure_from_menu()`;`_pick_battle_node(main)`/`_settle(frames)`/`_audit(screen, roots)`(本件既有)。 +产出:三私有函数 `_adventure_wiring_stage`/`_adventure_real_stage`/`_legend_two_stage`(T4 名实核对);battle_hud 实采样断言族。 + +- [ ] 新增 `_adventure_wiring_stage(main: Node) -> void`(async):职责=选路接线快速失败面。迁入现 :219-223 段(isolate_save tag "smoke_ui_struct_probe_adv"+种子 42+开冒险+_settle(4)+level_map 审计)与 :225-227 选路 emit;emit 注记改〔接线断言〕。 +- [ ] 在 `_adventure_wiring_stage` emit 后保留 _settle(6),再加消费断言:`main.run_scope.runner.awaiting_choice()` 为假,否则 `problems.append("[route_wiring] emit 选路未被消费(awaiting_choice 仍真)")`;候选无战斗节点时沿用现 :259 红句。 +- [ ] 新增 `_adventure_real_stage(main: Node) -> bool`(async):职责=选路真输入可达面。`isolate_save(main, "smoke_ui_struct_probe_adv_real", true, false, true)`(与 wiring 段同参,保两段候选一致)+种子 42 重钉+`_start_adventure_from_menu()`+_settle(4)(F6 先例形态)。 +- [ ] 在 `_adventure_real_stage` 加真点段:`_pick_battle_node` 取 id→`_cand_ids.find(id)` 取索引→`candidate_rect(index)`;矩形空或 id<0 → problems append 驱动中断、返回 false;否则 `ProbeUiUtil.push_click_at(main, rect.get_center())`+_settle(6)。 +- [ ] 在 `_adventure_real_stage` 真点后加落点三钉:`level_screen.visible` 假 ∧ `main.ui.screens.battle_root.visible` 真 ∧ `awaiting_choice()` 假;任一不满足 → problems append「[route_real] 真点选路未落战斗屏(逐项读数)」、返回 false;全过返回 true。 +- [ ] 新增 `_legend_two_stage(main: Node) -> void`(async):职责=图例开合两段面。第一段〔接线断言〕:`_btn_legend.pressed.emit()`→_settle→visible 断言→`await _audit("legend", […])`→`close()`→_settle→隐藏断言(现 :249-257 断言族原样迁)。 +- [ ] 在 `_legend_two_stage` 加第二段真输入:`ProbeUiUtil.push_click(main, _btn_legend)`→_settle→visible 断言→`ProbeUiUtil.find_button(legend_overlay, "关闭")` 真点关(钮缺=problems+close() 兜底,ui_click_probe:1229-1236 同款)→_settle→隐藏断言。 +- [ ] 重写 _ready 冒险簇调用序:`await _adventure_wiring_stage(main)` → `if await _adventure_real_stage(main):` 守卫内=宽度钉值断言(`_btn_legend.custom_minimum_size.x == 64.0`,否则 problems「[battle_hud] 图例钮宽度未统一 64」)→ battle_hud 审计+standeefit+状态面板段(现 :229-243 原样迁)→ `await _legend_two_stage(main)`。 +- [ ] 给三新函数各挂判据出处注记(内容锚:test-conventions.md「2. 场景级探针标配」两段式;图例函数另锚 HUD框架.md「提示与弹层:轻提示随起随消、重弹层排队进出」入栈出栈)。 +- [ ] 孤立直跑 ui_struct_probe.tscn 跑绿(equal_width 实采样停手/图例对=64/64)。 +- [ ] 孤立直跑 ui_click_probe.tscn 与 ui_input_probe.tscn 确认零回归(相邻真输入段)。 + +### T3 注记改锚(V5;0.1–0.15 日) + +取用:test-conventions「8.3 改动—验收对照表」批量模拟测量语义句(改锚目标)。产出:两处注记新锚(T4 审计核对)。 + +- [ ] 改 tune_sim_batch_parity_test.gd:166 注记为 `# 判据出处: design/engineering/test-conventions.md「8.3 改动—验收对照表」批量模拟测量语义 逐帧步进每局恰占一帧、n=0 同步收尾零帧(双形态对拍判据)`。 +- [ ] :199 同款改锚。 +- [ ] 跑单元测试全套件 `D:\code\godot\Godot_v4.7.2-stable_win64_console.exe --headless --path game --script res://tests/run_all.gd` 跑绿。 +- [ ] 跑 `python tools/capability_audit.py` 注记道零红(内容锚核验)。 + +### T4 产出物落位(0.1–0.25 日) + +取用:T1–T3 全部产出。产出:reports/ 两份+审计入口。 + +- [ ] 代码域闸全绿:`bash tools/run_all_gates.sh --code`(里程碑出口一次全套;波内修复只跑红件最小单元)。 +- [ ] 派未参与实现的只读子代理做独立验收审计(低档),报告落 `reports/iter-验收审计-<日期>.md`;未过不合回。 +- [ ] 落 `reports/iter-实现报告-<日期>.md`:各卡状态+实机目检总清单(目检项=AP 条停手/图例两钮宽度观感,登记不阻塞)+实现决定记录+渲染闸基线换代读数(若有)+equal_width 采样时停手钮 enable 态读数(disabled 会排除出等宽组,钉值断言腿已兜底,此处只记观测读数)。 +- [ ] 落 `reports/iter-反哺点-<日期>.md`:同步面四条逐条声明落点(预期零设计文档改动)。 +- [ ] 能力表名实核对:README 两新行代表用例名与落地函数逐字一致(不一致回表,禁实现批改 README)。 + +## 8. 验证闸(改动—验收对照表) + +| 需求点(判据出处锚) | 改动 | 验收测试 | 层级 | 真实入口 | 判据绑定面 | 能力行 | +|---|---|---|---|---|---|---| +| V1 选路两段式:design/engineering/test-conventions.md「2. 场景级探针标配」两段式 | ui_struct_probe.gd 冒险簇重写(_adventure_wiring_stage/_adventure_real_stage) | 接线消费断言(awaiting_choice 假)+真点落点三钉,problems 零(ui_struct_probe.gd:_adventure_wiring_stage/_adventure_real_stage) | 探针 | 第二段 push_click_at 真点候选命中矩形中心(第一段 emit 不充当真实入口) | awaiting_choice() 取值+level_screen/battle_root 可见性 | 新增:冒险簇选路两段式与战斗HUD实采样结构审计 | +| V2 battle_hud 实采样:design/engineering/test-conventions.md「2. 场景级探针标配」落点 | 同上(落点三钉守卫审计族) | battle_hud 结构审计+equal_width 实采样跑于可见根(ui_struct_probe.gd:_ready 战斗屏段) | 探针 | 同 V1 第二段 | 审计前落点 battle_root.visible 真+同容器按钮 size.x 读数 | 新增:冒险簇选路两段式与战斗HUD实采样结构审计 | +| V3 图例两段式:design/engineering/test-conventions.md「2. 场景级探针标配」两段式;design/gdd/systems/表现与支撑/HUD框架.md「提示与弹层:轻提示随起随消、重弹层排队进出」入栈出栈 | ui_struct_probe.gd:_legend_two_stage | 接线开合断言+真点开/真点「关闭」钮合断言,problems 零 | 探针 | 第二段 push_click 图例钮/关闭钮真点 | legend_overlay.visible 开合读数 | 新增:图例层两段式开合 | +| V4 两钮统一 64px:design/ux/battle.md「Component Inventory」按钮组等宽纪律 | ap_bar_view.gd:102 56→64 | 钉值断言(custom_minimum_size.x==64.0)+equal_width 审计(ui_struct_probe.gd:_ready 战斗屏段) | 探针 | V1 第二段真点选路落战斗屏 | _btn_legend.custom_minimum_size.x+同容器 size.x 差 ≤1 | 新增:冒险簇选路两段式与战斗HUD实采样结构审计 | +| V5 注记改锚:design/engineering/test-conventions.md「8.3 改动—验收对照表」批量模拟测量语义 | tune_sim_batch_parity_test.gd:166/:199 注记 | 五面对拍套件原样跑绿(tune_sim_batch_parity_test.gd:_init)+capability_audit 注记内容锚核验 | 单元 | TuneSimController.run()(对拍套件驱动,调试接口直改类) | 五面对拍断言(不改)+注记关键词命中节块 | 既有:调参测速批量模拟(逐帧步进与统计读数) | + +- 测试削弱申报:零旧断言删除、零阈值放宽、零豁免新增(WL 保持空);emit 注记由「前提注入(保留 emit)」改写为〔接线断言〕标记,断言族本身不变。 +- 闸口径:重闸=tools/run_all_gates.sh 按本批改动域选档;里程碑步(T 段)出口跑一次全套闸,波内修复只做出红最小单元的最窄确认,新增测试/工具先行孤立验证再并入全套。 +- 测试方式两分法:V1–V5 全归调试接口/探针验;用户目检一项(AP 条两钮宽度观感)入实现报告实机目检总清单,登记不阻塞。 +- 独立验收审计:入口=T4 只读子代理;报告=reports/iter-验收审计-<日期>.md;低档梯度(test-conventions §8.7)。 + +## 9. 异常分级 + +- L1 自救:_settle 帧数微调(4–8 帧域内);problems 红句措辞;隔离 tag 命名微差。 +- L2 记录继续:渲染闸 golden 红→基线换代呈用户审核(登记不阻塞);探针覆盖登记件读数漂移。 +- L3 停机写报告等用户:C-1~C-5 任一触碰;真输入选路落点不稳(T2 软盒超);要改产品码才能让探针通过(C-2 互斥);机检预算互斥=上游缺陷停卡退回写卡段。 + +## 10. 代拍板白名单 + +- 隔离存档 tag 命名(smoke_ui_struct_probe_adv_real 同形)。 +- _settle 帧数(4–8 帧域内取值)。 +- problems 红句措辞与逐项读数格式。 +- 三新函数在 ui_struct_probe.gd 内的落位次序。 + +超清单微决策一律记入实现报告「实现决定记录」节。 + +## 11. 待裁点 + +零待裁点,开工门=U0。四项裁决已全部落地(用户 2026-11-09:①③两段式先后有序、②统一 64px、④落 test-conventions 测量面节、等宽句入 battle.md),规格三句已定稿在场。 + +## 12. 落位与可复用性预检 + +新增文件零;新增数据件零;新增函数三(均在 ui_struct_probe.gd 内): + +- `_adventure_wiring_stage`/`_adventure_real_stage`/`_legend_two_stage`: + - 复用面:驱动全复用 ProbeUiUtil 既有面(isolate_save/push_click_at/push_click/find_button,F8)——不新造 push_input 封装;重开冒险复用 `_start_adventure_from_menu`(ui_click_probe:615-619 先例);命中矩形复用 `candidate_rect` 读口(F7)。grep 同职责零命中(库内无 adventure_wiring/route_real/legend_two_stage 同名同义件)。为什么不能复用既有那一个:ui_click_probe 的图例段是其主循环内同步形态(零 await、_tested_legend 旗标守卫),与本件 _ready 协程结构审计族不同形,强共用会跨探针耦合两段流程;三函数按职责拆出(接线快速失败面/真输入可达面/图例开合面),各带单一变化原因,_ready 净缩短(F13)。 + - 唯一面:宽度值 64 只改 ap_bar_view.gd:102 一处(停手钮 :62 已是 64,无第二处定义);两段式驱动逻辑只落本件,不落第二份 helper;注记锚句只改两处现存注记,不另立锚清单。 + - 分层与交互面:探针 → ProbeUiUtil(共用面)→ Viewport.push_input(引擎输入管线);探针只读产品读口(awaiting_choice/candidate_rect/_cand_ids——后两者探针读取先例在案 :259/:470);产品码写面零(C-2)。 + +## 13. 禁为机检文本保留无效成员 + +本卡含探针重写(重构性质):禁止为迎合机检消息文本(含计数)保留或新增无效成员/别名;机检键与卡片契约互斥时实现段一律停卡呈报,不得自造第三条路(同 C-4,判据权威=code-conventions §1.1)。 + +## 14. 实现规范预算 + +- 新增文件零 → 新件三查不适用。 +- 存量触面一查:三触面文件在 tools/gdstyle_baseline.txt 零登记键(F11,grep 实查)——无「S13 键较登记值只降不升」存量义务;改后若 S13 出新红=新键超标,按 L3 机检预算互斥处置,禁抬基线换绿。 +- 新增三私有函数预算:单函数分支 ≤8、返回 ≤6(_adventure_real_stage 三返回出口);ui_struct_probe.gd 成员变量维持 1(problems)、公开方法零新增(三函数均私有);_ready 内联冒险簇段迁出后净缩短。 + +## 15. 拆分边界纪律 + +条款见 C-5(判据权威=code-conventions §1.1,不复制定文)。拆出单元职责语句与集体身份:接线段=选路接线快速失败面;真输入段=选路真输入可达面;图例两段=图例开合两段面——三名各有单一变化原因,非「剩下的成员」打包。实现报告逐件一行承载。 + +## 16. 验收档申报 + +低(头部已申报)。判据=失败代价单维:宽度改错即看即知、无状态残留;探针/注记改错不随存档或结算传播。U0 时用户确认或改判。 + +## 17. 复核记录 + +| 轮次 | 复核者身份 | 发现 | 去向 | 处置结果 | +|---|---|---|---|---| +| 1 | 只读子代理(general-purpose,未参与本卡撰写) | §14 预算「_adventure_real_stage 两返回出口」与 T2 三步(false/false/true)共三返回不符 | 自判 | 改「三返回出口」(≤6 预算仍满足);依据=卡 T2 真点段三步声明 | +| 1 | 同上 | T2 真输入段 isolate_save 只写 tag+种子,未显式钉三参;两段候选一致依赖与 wiring 段同参 | 补写 | T2 步骤补确切调用 `isolate_save(main, "smoke_ui_struct_probe_adv_real", true, false, true)`;依据=ui_struct_probe.gd:219、ui_click_probe.gd:615 先例同参 | +| 1 | 同上 | equal_width 腿若采样时停手钮 disabled 则排除出组、该腿空转(钉值断言腿已兜底不假绿) | 自判 | 不改判据;T4 实现报告步骤补「采样时停手钮 enable 态读数」观测义务;依据=ui_struct_probe.gd:710/:791-792 可见按钮采集口径 | + +其余审点(验收三问 V1–V5、F1–F13 实读对账、预检与结构图、拆分边界、引擎 4.7.2 三查、C-2 契约自洽与重开冒险路径、能力表名实、三判据锚节块命中)零发现。无待裁、无退回上游。 + +复核报告落盘:reports/复核-测试面四项收口批-2026-11-10.md \ No newline at end of file diff --git a/待办清单.md b/待办清单.md index 89bf69f4..b71bfe2d 100644 --- a/待办清单.md +++ b/待办清单.md @@ -292,11 +292,11 @@ #### 测试面真输入化批发现四项待裁(2026-11-06 登记,来源=批次移交) -**实况**:真输入化批实现中坐实——①route 选路信号路径屏幕切换时序:ui_struct_probe emit 选路后 battle_root 持续不显示,battle_hud 结构审计长期空转采样(假绿面)。②AP 条停手钮(64px)/图例钮(56px) 同容器宽度不等——equal_width 纪律真违规。③图例开启真输入承载待①裁决(两探针图例段保留 emit+前提注记)。④tune_sim_batch_parity(调参测量域)无 design/ 规格句可锚——注记规格缺口(机制事实源=architecture:168)。证据=test-oracle-anchor 分支批内提交(git 历史可考)+ui_struct_probe.gd 前提注记。 +**实况**:四项全裁(2026-11-09 用户裁),设计定稿=design/engineering/test-conventions.md v1.0(§2 两段式:先接线断言快速失败、后真输入保可达;§8.3「批量模拟测量语义」句=④规格落点)+design/ux/battle.md「按钮组等宽纪律」句(②判据锚,停手/图例钮统一 64px)。①③定性=探针问题非游戏 bug(emit 绕过视图置隐前提,证据=game/probe/ui_struct_probe.gd:227:249 注记)。①②③修复+④测试注记改锚已编成一张卡:reports/需求卡片-测试面四项收口批-2026-11-10.md(复核通过,报告=reports/复核-测试面四项收口批-2026-11-10.md;能力表两新行已随卡入 game/tests/README.md)。 **改动面**:游戏代码+文档 -**状态**:待执行 +**状态**:已写卡 #### 色板近色欠账六对清偿(2026-11-07 登记,来源=批次移交)