From b0b0cd0c8193c33c1e947d730db98552e8c7d7b9 Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Sat, 7 Nov 2026 00:09:11 +0800 Subject: [PATCH] =?UTF-8?q?=E5=86=99=E5=8D=A1(QA=20harness=E7=BC=BA?= =?UTF-8?q?=E9=99=B7=E6=94=B6=E5=8F=A3=E6=89=B9=C2=B7=E5=8D=A1=E7=89=87?= =?UTF-8?q?=E6=88=90=E7=AB=8B+=E5=A4=8D=E6=A0=B8=E5=87=AD=E6=8D=AE?= =?UTF-8?q?=E6=8D=A2=E4=BB=A3):=20=E9=9C=80=E6=B1=82=E5=8D=A1=E7=89=87?= =?UTF-8?q?=E8=90=BD=E6=A1=A3=20reports/=E9=9C=80=E6=B1=82=E5=8D=A1?= =?UTF-8?q?=E7=89=87-QA=E7=BC=BA=E9=99=B7=E6=94=B6=E5=8F=A3=E6=89=B9-2026-?= =?UTF-8?q?11-06.md(A2=E7=BB=88=E5=B1=80=E7=BB=93=E7=AE=97=E6=A1=86:194/:3?= =?UTF-8?q?31=E5=8F=8C=E7=82=B9has=5Fmeta=E5=AE=B9=E9=94=99/B1=E5=81=9C?= =?UTF-8?q?=E6=89=8B=E9=92=AE=E7=9C=9F=E8=BE=93=E5=85=A5=E6=8E=A2=E9=92=88?= =?UTF-8?q?=E5=AE=9A=E5=9E=8B=E6=AE=B5+=E8=87=AA=E5=8A=A8=E8=AF=95?= =?UTF-8?q?=E7=8E=A9=E5=81=9C=E6=89=8B=E8=A1=8C=E4=B8=BA/B2=E8=A7=86?= =?UTF-8?q?=E5=9B=BE=E6=96=B9=E6=B3=95=E5=8F=A3=E5=85=A8=E6=B8=8541?= =?UTF-8?q?=E5=A4=84=E8=BD=AC=E7=9C=9F=E8=BE=93=E5=85=A5+=E6=AD=BB?= =?UTF-8?q?=E6=8E=A5=E7=BC=9D11=E6=96=B9=E6=B3=95=E6=B8=85=E7=90=86;=20?= =?UTF-8?q?=E8=A7=84=E6=A0=BCS1-S5=C2=B7=E4=BB=BB=E5=8A=A1=E5=8D=A1T1-T7?= =?UTF-8?q?=C2=B7=E5=AF=B9=E7=85=A7=E8=A1=A8R1-R9=C2=B7=E4=BC=B0=E6=97=B6?= =?UTF-8?q?=E4=B8=AD=E5=80=BC4.875=E5=B7=A5=E4=BD=9C=E6=97=A5);=20?= =?UTF-8?q?=E8=83=BD=E5=8A=9B=E6=B8=85=E5=8D=95=E5=A2=9E3=E8=A1=8C(?= =?UTF-8?q?=E7=BB=88=E5=B1=80=E9=9B=B6=E6=8A=A5=E9=94=99/=E5=81=9C?= =?UTF-8?q?=E6=89=8B=E7=9C=9F=E8=BE=93=E5=85=A5/=E5=81=9C=E7=82=B9?= =?UTF-8?q?=E9=93=BE=E7=9C=9F=E8=BE=93=E5=85=A5=E2=80=94=E2=80=94=E7=9C=9F?= =?UTF-8?q?=E5=AE=9E=E5=85=A5=E5=8F=A3=E6=A0=BC=E5=8F=AF=E6=A0=B8=E5=BD=A2?= =?UTF-8?q?=E6=80=81);=20=E5=BE=85=E5=8A=9E=E6=9D=A1=E7=9B=AE=E6=8E=A8?= =?UTF-8?q?=E8=BF=9B=E5=B7=B2=E5=86=99=E5=8D=A1(=E5=8D=A1=E7=89=87?= =?UTF-8?q?=E8=B7=AF=E5=BE=84=E5=85=A5=E5=AE=9E=E5=86=B5);=20=E5=A4=8D?= =?UTF-8?q?=E6=A0=B8=3D=E5=8F=AA=E8=AF=BB=E5=AD=90=E4=BB=A3=E7=90=861?= =?UTF-8?q?=E8=BD=AE11=E5=8F=91=E7=8E=B0=E5=85=A8=E5=A4=84=E7=BD=AE(?= =?UTF-8?q?=E8=A1=A5=E5=86=998=E5=90=ABjourney:449/:457=E6=98=A0=E5=B0=84?= =?UTF-8?q?=E9=94=99=E6=8E=A7=E4=BB=B6=E4=B8=8EA2=E6=BC=8F:331=E5=90=8C?= =?UTF-8?q?=E5=9E=8B=E7=AC=AC=E4=BA=8C=E5=A4=84=E4=B8=A4=E5=AE=9E=E8=B4=A8?= =?UTF-8?q?/=E8=87=AA=E5=88=A43)=E9=9B=B6=E5=BE=85=E8=A3=81;=20=E5=A4=8D?= =?UTF-8?q?=E6=A0=B8=E5=87=AD=E6=8D=AE=E6=8D=A2=E4=BB=A3=3D=E5=A4=8D?= =?UTF-8?q?=E6=A0=B8=E8=AE=B0=E5=BD=95=E8=8A=82=E5=8D=B3=E5=87=AD=E6=8D=AE?= =?UTF-8?q?=E4=B8=8D=E5=8F=A6=E8=AE=BE=E6=8A=A5=E5=91=8A=E6=96=87=E4=BB=B6?= =?UTF-8?q?(=E5=85=AD=E5=A4=84=E5=90=8C=E6=89=B9:=20=E9=97=B8C6=E5=88=A0?= =?UTF-8?q?=E7=94=B3=E6=8A=A5=E5=9C=A8=E7=9B=98=E4=B8=A4=E6=9F=A5/doc-conv?= =?UTF-8?q?entions=E5=B7=B2=E5=86=99=E5=8D=A1=E8=AF=81=E6=8D=AE=E9=A1=B9/p?= =?UTF-8?q?rocess-conventions=E6=AE=B5=E4=B8=89=E6=AE=B5=E5=9B=9B/req-card?= =?UTF-8?q?=E5=9B=9B=E5=A4=84/iter-plan=E4=BA=94=E6=9F=A5=E2=91=A3?= =?UTF-8?q?=E2=80=94=E2=80=94=E5=90=8E=E4=B8=A4=E4=BB=B6=E4=B8=BB=E5=8C=BA?= =?UTF-8?q?=E7=9B=B4=E6=94=B9=E4=B8=8D=E5=85=A5git);=20=E9=97=B8=E4=BB=B6?= =?UTF-8?q?=E5=85=9C=E5=BA=95=3Dcapability=5Faudit=20GBK=E6=8E=A7=E5=88=B6?= =?UTF-8?q?=E5=8F=B0=E6=89=93=E5=8D=B0=E7=BA=A2=E9=A1=B9=E5=8D=B3=E5=B4=A9?= =?UTF-8?q?=E5=8A=A0utf-8=E9=87=8D=E9=85=8D=E7=BD=AE=E3=80=82=E8=AF=BB?= =?UTF-8?q?=E6=95=B0:=20=E6=B5=81=E6=B0=B4=E7=BA=BF=E9=97=B8PASS(27?= =?UTF-8?q?=E6=9D=A1=E7=9B=AE=C2=B7=E5=8D=A1=E7=89=87=E5=8F=A3=E5=BE=842?= =?UTF-8?q?=E5=BC=A0=E5=85=A8=E8=BF=87)+--docs=E3=80=90=E9=AA=8C=E6=94=B6?= =?UTF-8?q?=E9=80=9A=E8=BF=87=E3=80=91=E6=97=A0=E6=96=B0=E5=A2=9E=E7=BA=A2?= =?UTF-8?q?+=E8=83=BD=E5=8A=9B=E5=AE=A1=E8=AE=A1=E7=BA=A20(=E8=83=BD?= =?UTF-8?q?=E5=8A=9B=E8=A1=8C106)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- design/engineering/doc-conventions.md | 2 +- design/engineering/process-conventions.md | 4 +- game/tests/README.md | 3 + reports/需求卡片-QA缺陷收口批-2026-11-06.md | 238 ++++++++++++++++++++ tools/capability_audit.py | 6 + tools/pipeline_gate.py | 12 +- 待办清单.md | 4 +- 7 files changed, 253 insertions(+), 16 deletions(-) create mode 100644 reports/需求卡片-QA缺陷收口批-2026-11-06.md diff --git a/design/engineering/doc-conventions.md b/design/engineering/doc-conventions.md index 1659f09b..6f075972 100644 --- a/design/engineering/doc-conventions.md +++ b/design/engineering/doc-conventions.md @@ -181,7 +181,7 @@ 设计线段与下游段同条并存是合法形态:状态行里出现过的**每条设计线各自留最新一段**,跨线依赖不阻塞本条推进(文档线闭合后写卡、美术线仍未出图,就把 `文档设计已闭合` 与 `待美术设计` 并写)。「写卡前本条要落的那条设计线必须已闭合」是实现侧的执行义务,由编排段查卡片凭据核对,不靠标题声明——闸只查同线并现多段。 -状态行只写状态词:去掉特批标记与「(备选)」后缀后,残留任何括号即违规。闭合类状态词(文档设计已闭合/美术设计已闭合/已写卡/已写入)的证据——设计定稿路径+版本、art-bible 条款版本、需求卡片路径、复核报告路径(「已写卡」段另须报这一项,2026-11-05 用户立规;对文件名日期 ≥2026-11-06 的卡生效,旧卡不回头改,核对由 `tools/pipeline_gate.py` 的卡片复核判据到卡正文做)、落点文档+版本——一律写在实况的关联文档清单里,由流水线闸到正文核对;已编迭代 N 段的交叉核依据=实况清单里的需求卡片路径。 +状态行只写状态词:去掉特批标记与「(备选)」后缀后,残留任何括号即违规。闭合类状态词(文档设计已闭合/美术设计已闭合/已写卡/已写入)的证据——设计定稿路径+版本、art-bible 条款版本、需求卡片路径(「已写卡」段的复核凭据=卡内「复核记录」节,2026-11-06 用户裁:不另设复核报告文件;对文件名日期 ≥2026-11-06 的卡生效,旧卡不回头改,核对由 `tools/pipeline_gate.py` 的卡片复核判据到卡正文做)、落点文档+版本——一律写在实况的关联文档清单里,由流水线闸到正文核对;已编迭代 N 段的交叉核依据=实况清单里的需求卡片路径。 三种条目形态与一种后缀: diff --git a/design/engineering/process-conventions.md b/design/engineering/process-conventions.md index 4a9764ae..25425c72 100644 --- a/design/engineering/process-conventions.md +++ b/design/engineering/process-conventions.md @@ -23,8 +23,8 @@ |---|---|---|---| | 一·登记 | 无(闸管格式) | 待办清单条目 | 条目=标题登记元数据(日期/来源/可选优先级)+正文四属性(实况/缺口/改动面/状态);标题登记后不再变,正文随进程演进。格式与状态机权威=doc-conventions 第 12 节 | | 二·文档设计/美术设计 | doc-design(文档线,兼任反哺点写入)/asset-ingest(美术录入;样张素材由用户主导产出) | GDD 文档或 art-bible/过审样张素材;画面类需求另出预览图(文档线,2026-11-05 用户裁) | 用户提起或从待办清单取出;会话内进行、用户主导、禁无监管自跑;经用户点头确认心智一致才许写入文档;完成判据=待裁点清零,带未裁点的是讨论稿;设计线闭合凭据记入待办清单实况清单(文档线=文档路径+版本号,美术线=art-bible 条款版本);缺哪条线写在缺口属性,闭合与否写在状态段。画面类需求(新增画面要素/布局/配色/动效等触碰画面呈现规格的改动)设计段先出预览图=目标画面的 HTML/SVG 效果图(diagram-design 通道,AGENTS.md 图优先的同款载体),经用户人审通过才许进写卡段;预览图内嵌对应 ux/ 规格文档并随附像素级视觉判据句(§7 第 2 条同款写法);缺陷修复以现行规格与在库基线为准,不触发新预览 | -| 三·写需求卡片 | req-card | 需求卡片 | 设计线闭合后用户发令;新玩法/新系统/新内容必须有设计定稿前置,例外=需求性工程条目(缺陷修复/重构等改游戏行为)凭实况里的证据指认跳过设计线;配套维护类(工程债/测试基建/工具维护,不动游戏行为)=工程改动直改类,不走本段,由用户发令直改;卡片必经 grilling 多轮复核、零待裁点才成立;复核发现按四类去向处置(2026-11-05 用户立规,定义在 req-card 技能「复核发现四类分流」:自判=查权威文档或查代码现状有唯一答案,复核者自己下结论改卡;补写=卡里漏写,回炉补全;待裁=几种做法都不违规且代价不同、影响玩法取向,才交用户;退回上游=文档设计线未闭合、美术设计线未闭合、或架构与代码规范本身冲突,停笔退对应段);成立凭据=卡内「复核记录」节+该节申报的复核报告路径,顺序未走完禁对用户称完成、禁落 commit(同 §1 第 2 条卡片复核前置判据);写完在待办清单状态记「已写卡」,卡片路径与复核报告路径记入实况清单(防遗忘);画面类需求卡片必引设计段已人审的预览图(验收判据的判据出处行锚指向 ux/ 内嵌预览节,test-conventions §8.3 锚口径不变) | -| 四·迭代编排 | iter-plan | roadmap 迭代行 | 编排五查:①每卡卡片文件存在 ②每卡设计闭合凭据齐(或需求性工程条目的证据指认)③估时与冻结线——所选卡估时按区间**中值**求和(单位工作日、写精确值不取整):**卡片任何工作量均可编入**(2026-10-25 用户立:工作量限制属迭代层、非卡片层);编入后迭代总量 <5 个工作日=迭代行状态「冻结待凑批」、不可开工,凑批 ≥5 后由编排段改「待开工」(迭代体量偏好,2026-10-21 用户立、2026-10-25 改冻结制);5–10 个工作日为常规区间;超过 10 个工作日须经用户确认(确认前呈报整批/拆批两案等裁,禁自行拆分或塞入),确认后迭代行随带日期特批标记;超过 20 个工作日禁止编(硬上限,用户确认也不放行,必须拆批)④每卡复核记录在位(2026-11-05 用户立规)——卡内有「复核记录」节、该节申报的复核报告文件在 `reports/` 盘上真实存在;缺则呈报退回写卡段,禁编入,本段不代跑复核也不代补记录(生效=卡片文件名日期 ≥2026-11-06,旧卡不回头改)⑤写完 roadmap 行后跑流水线闸确认绿;编入未完成迭代,新开迭代行经用户确认 | +| 三·写需求卡片 | req-card | 需求卡片 | 设计线闭合后用户发令;新玩法/新系统/新内容必须有设计定稿前置,例外=需求性工程条目(缺陷修复/重构等改游戏行为)凭实况里的证据指认跳过设计线;配套维护类(工程债/测试基建/工具维护,不动游戏行为)=工程改动直改类,不走本段,由用户发令直改;卡片必经 grilling 多轮复核、零待裁点才成立;复核发现按四类去向处置(2026-11-05 用户立规,定义在 req-card 技能「复核发现四类分流」:自判=查权威文档或查代码现状有唯一答案,复核者自己下结论改卡;补写=卡里漏写,回炉补全;待裁=几种做法都不违规且代价不同、影响玩法取向,才交用户;退回上游=文档设计线未闭合、美术设计线未闭合、或架构与代码规范本身冲突,停笔退对应段);成立凭据=卡内「复核记录」节(2026-11-06 用户裁:不另设复核报告文件),顺序未走完禁对用户称完成、禁落 commit(同 §1 第 2 条卡片复核前置判据);写完在待办清单状态记「已写卡」,卡片路径记入实况清单(防遗忘);画面类需求卡片必引设计段已人审的预览图(验收判据的判据出处行锚指向 ux/ 内嵌预览节,test-conventions §8.3 锚口径不变) | +| 四·迭代编排 | iter-plan | roadmap 迭代行 | 编排五查:①每卡卡片文件存在 ②每卡设计闭合凭据齐(或需求性工程条目的证据指认)③估时与冻结线——所选卡估时按区间**中值**求和(单位工作日、写精确值不取整):**卡片任何工作量均可编入**(2026-10-25 用户立:工作量限制属迭代层、非卡片层);编入后迭代总量 <5 个工作日=迭代行状态「冻结待凑批」、不可开工,凑批 ≥5 后由编排段改「待开工」(迭代体量偏好,2026-10-21 用户立、2026-10-25 改冻结制);5–10 个工作日为常规区间;超过 10 个工作日须经用户确认(确认前呈报整批/拆批两案等裁,禁自行拆分或塞入),确认后迭代行随带日期特批标记;超过 20 个工作日禁止编(硬上限,用户确认也不放行,必须拆批)④每卡复核记录在位(2026-11-05 用户立规;2026-11-06 用户裁凭据换代——复核凭据=「复核记录」节自身,不另查报告文件)——卡内有「复核记录」节;缺节或节内任一条发现没有去向标记则呈报退回写卡段,禁编入,本段不代跑复核也不代补记录(生效=卡片文件名日期 ≥2026-11-06,旧卡不回头改)⑤写完 roadmap 行后跑流水线闸确认绿;编入未完成迭代,新开迭代行经用户确认 | | 五·实现 | iter | 代码与配置,可运行的游戏 | 需求卡片永不单独施工,统一由用户指定迭代号触发(=U0 开工令),按 iter 技能与本文 §3 执行;**本段是代码实现批:禁写 `design/` 与根规则文件,产出物只落 `reports/`(见 §3 第 12 条)**;设计权威文档(GDD/art-bible)批内一律不更新;完成人闸=实机目检清单+实现决定记录写齐即完成批内义务;画面类需求实现批另按 test-conventions §8.2 黄金图基线冻结口径执行(实跑截图入基线前用户对照预览图确认一眼,此后渲染闸自动盯) | **实现段零裁断**:实现段的输入在编排段出口已锁死(卡片零待裁点+设计闭合凭据齐+编排五查过)。实现中冒出卡片没写清的分歧=上游缺陷——停该卡、待办清单状态回退+缺口补记,退回上游;禁自答、禁内联提问求裁断;该卡停摆不阻塞同迭代其他卡。环境故障与测试红走异常分级(自救重试/记录继续/停机呈报)。代拍板白名单保留:授权发生在卡片审问阶段,实现只执行预授权;超白名单/超卡片明列范围事项记入实现报告「实现决定记录」节备案,不另立追认单。 diff --git a/game/tests/README.md b/game/tests/README.md index 62f9242a..802b3ab5 100644 --- a/game/tests/README.md +++ b/game/tests/README.md @@ -168,6 +168,9 @@ tests/ | 减动效开关存储契约(持久化回读/缺省值/引擎动效档应用) | 设置与本地化 | `SettingsStore.load_settings()`/`save_settings()`/`apply()` | `settings_store_test.gd:_test_settings_roundtrip`;`settings_store_test.gd:_test_settings_default`;`settings_store_test.gd:_test_settings_apply_chain` | | 营地顶栏 HUD 钥石读数与刷新单口同步 | 营地 HUD 栏 | 隔离存档实例 `meta_state._add_keystone()`→ 显式触发 `CampRefreshBus.refresh(camp_data)` → `camp_hud_band.refresh()` → `keystone_badge` 读数 | `screen_flow_probe.gd:_ready`(HUD 余额读数/刷新段);`ui_struct_probe.gd:_ready`(顶栏位结构段) | | 营地五窗统一窗壳形态 | 营地五界面 | 七物件命中区/笔记本 → `CampSceneView._gui_input()`(`object_pressed` 信号)→ 组合根分派开窗;窗板几何(居中定尺寸 720×640 起点)/遮罩/窗内滚动面为呈现提交面 | `screen_flow_probe.gd:_step_camp_window_shell`(窗壳形态段) | +| 终局结算框关闭动线零引擎报错 | 战斗表现 | fx_probe/screen_flow_probe 真实败走关闭动线(`BattleEndOverlay.open_defeat()` → `BattleEndOverlay.close()`)孤立直跑,日志零报错行读数 | `fx_probe.gd:_ready`(计划测试——需求卡片「QA harness 缺陷与覆盖遗漏收口批」2026-11-06 锚定) | +| 停手钮真输入命中与停手收轮落效 | 行动经济 | 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 锚定) | **旅程段七:数据配置与跨系统契约** diff --git a/reports/需求卡片-QA缺陷收口批-2026-11-06.md b/reports/需求卡片-QA缺陷收口批-2026-11-06.md new file mode 100644 index 00000000..cac8dac8 --- /dev/null +++ b/reports/需求卡片-QA缺陷收口批-2026-11-06.md @@ -0,0 +1,238 @@ +# 需求卡片——QA harness 缺陷与覆盖遗漏收口批(2026-11-06) + +> **来源**:待办清单「QA harness 三批缺陷与覆盖遗漏收口」条目(P0,2026-11-06 批次移交登记)——需求性工程条目,状态行整行无设计线段、首段落「待写卡」。 +> **设计事实源(唯一事实源)**:`reports/QA-harness三批-缺陷与覆盖遗漏报告-2026-11-06.md`(A2=其§一 A2、B1=其§二 B1、B2=其§二 B2,逐条带文件:行号与登记处指针)+待办清单条目实况同源指认。设计线跳过依据=需求性工程条目(缺陷修复+测试驱动面,凭实况里的证据指认跳过设计线,doc-conventions §12.1)。 +> 验收档:中——判由:改动面=呈现层一行级容错(A2)与探针/测试驱动面(B1/B2);做错的后果不随存档或结算传播(本批零持久状态触碰),但覆盖登记件读数进证据链,失真并非即看即知,按三档判据取中。A2 单看属低档,本卡多面按最高档申报。 +> **预计周期(估时中值和)**:≈4.875 个工作日(编排段按区间中值核对的口径;T1–T7 逐卡区间见各卡头)。 +> **范围检查**:单卡单子系统——三件缺陷同源于 QA harness 三批的同一发现面(探针真输入化与覆盖登记),拆卡只增加合并登记次数,不拆。 + +## 1. 目标与完成定义 + +本批做三件事:修一个探针跑批持续输出的引擎报错噪声(A2);把停手钮的「存在但从未被真输入点到」驱动空洞补成确定性覆盖(B1,探针+自动试玩两处);把探针族与测试宿主里剩余的「视图方法口驱动」全部换成真输入管线驱动(B2,全清 41 处)。 + +规格项(每条指到任务卡与对照表行): + +- S1 终局结算框关闭动线零引擎报错——T1、对照表 R1。 +- S2 停手钮使能窗真输入命中、命中登记与停手收轮落效(探针定型化段)——T2、对照表 R2。 +- S3 自动试玩(journey_player)停手行为入线,停手成为全动线真输入行为之一——T3、对照表 R3。 +- S4 视图方法口驱动全清转真输入——S4a ui_click_probe 16 处(T4、R4);S4b 其余 7 探针 11 处(T5、R5/R6);S4c journey_player 8 处(T3、R3 附属);S4d 非探针层 6 处(T6、R7/R8)。 +- S5 转换后零调用的 press_* 死接缝同批删除——T4/T6、对照表 R9。 + +完成定义=S1–S5 全部有对照表行、每行验收断言在当轮真实跑批执行并通过、独立验收审计通过、合回后远端 CI(游戏码批全量档)绿。 + +## 2. 设计事实源 + +见头部声明。证据指认逐条(与待办清单条目实况一致): + +- A2:`game/presentation/views/battle_end_overlay.gd:194`——`get_meta(&"celebrate_tw", null)` 在 meta 缺失时引擎仍打印报错(当前引擎版对显式 null 缺省值照样报错);败走/放弃路径每次触发(`game/probe/fx_probe.gd:58-66` 的 open_defeat→close 循环、screen_flow_probe 终局段)。关闭动线功能不受影响,属持续日志噪声。 +- B1:两探针与自动试玩均未以真输入点过停手钮;覆盖面板控件下钻(ui_click 探针 seen 91/命中 27)与 `probe_hits_ui_click.js` 零停手键。驱动代码其实在——`game/probe/ui_click_probe.gd:1063-1065` 已是 `ProbeUiUtil.push_click` 真输入,但触发条件(已花 ≥3 AP 时 15% 随机)实际跑批从未命中使能窗,随机静默回退。 +- B2:视图方法口驱动清单(本次逐处 grep 复核后共 41 处,分四类面,见 §3)。 + +## 3. 现状事实(代码级,开工自行复核;行号以 2026-11-06 master 7aa0126b 为准) + +**A2 面**: + +- `game/presentation/views/battle_end_overlay.gd:194`:`var tw: Tween = get_meta(&"celebrate_tw", null)`——败走路径(open_defeat,:175-186)不设该 meta,close()(:189-198)每次在此报错。同型第二处=`battle_end_overlay.gd:331`(`_play_celebrate` 取同一 meta——close 后已 remove_meta(:197),下一次 open_victory 到此同款报错)。 +- 报错形态为引擎层打印,场景探针闸的脚本错误扫描(`tools/probe_gate.sh:49` 经 `tools/error_scan.py`)不判红——闸绿但噪声持续,故验证形态=探针孤立直跑+日志零该报错行读数。 +- `ui_run_modals.gd:10`:`end_overlay: BattleEndOverlay`——screen_flow_probe 的「终局」即本件。 + +**B1 面**: + +- `game/probe/ui_click_probe.gd:1041-1045`:停手触发=已花 ≥3 AP 时 15% 随机、或无挖可走时;:1063-1065 `_click_stop()`=`ProbeUiUtil.push_click(main, main.ui.battle.board_zone.ap_bar._btn_stop)`。 +- 使能投影:`game/presentation/hud_presenter.gd:92`(alive∧digging)→ `game/presentation/views/ap_bar_view.gd:146-147`(`_btn_stop.disabled`)。 +- 停手消费端:`game/presentation/main.gd:690` `_on_stop_pressed` → `settle_batch([{"action":"stop"}])`(批次唯一结算入口,排雷玩法.md:162);停手=玩家主动收轮(排雷玩法.md:167);已清图时 voided(toast「本轮已清图,停手未执行」)。 + +**B2 面——方法口驱动全清单(41 处,本次 grep 复核)**: + +| 组 | 调用点 | +|---|---| +| ①ui_click_probe 点名三组(16 处) | `ui_click_probe.gd:426`、`:536`(press_candidate);`:448`、`:656`(node_overlay.press_continue);`:473`、`:475`、`:476`、`:478`、`:479`、`:481`、`:649`、`:651`、`:652`、`:654`(curio press_continue/press_card/press_confirm);`:972`、`:975`(ap_bar press_refresh_for_probe/press_confirm_for_probe) | +| ②journey_player 方法口(8 处) | `journey_player.gd:380`(node_overlay.press_continue);`:441`(press_candidate);`:449`、`:457`(curio press_continue);`:451`、`:452`、`:454`、`:455`(curio press_card/press_confirm) | +| ③其余探针到达型+停点+调试浮窗(11 处,7 件) | `fx_shot_probe.gd:47`、`ui_tune_probe.gd:109`、`shot_probe.gd:147`、`ui_probe.gd:83`、`t17_defer_probe.gd:39`、`layout_probe.gd:32`(press_candidate);`ui_struct_probe.gd:257`(node_overlay.press_continue);`ui_tune_probe.gd:59`、`:62`、`:67`、`:97`(debug press_apply/press_reset/press_simulate_for_probe) | +| ④非探针层(6 处) | `system_test.gd:433`(press_candidate);`reward_overlay_test.gd:60`、`:64`、`:65`、`:66`、`:76`(press_refresh/press_card/press_confirm/press_continue) | + +**被点控件形态(真输入可行性依据)**: + +- 三选一卡=BCard gui_input 点选(`curio_pick_overlay.gd:157-160` M7 注——真实路径与 press_card 同一 `_select_card` 处理器);确认/继续/刷新=真 Button(:163-173 emit 形态即假入口)。 +- 节点停点=真 Button(`node_overlay.gd:32-34`)。 +- 弃图刷新=真 Button `_btn_refresh`(`ap_bar_view.gd:110-111` 创建+接线,disabled 守卫=真实拒绝路径);确认 chips=真 Button(:88-96,`_confirm_row` 子件)。 +- 地图候选=自绘命中路径:`level_map_screen.gd:469-479` press_candidate 内部走「节点中心坐标 → `_candidate_at` 命中检测 → 提交」——真输入化=点候选命中矩形中心,经画布 gui_input 走同一命中面。 +- 非探针层宿主在树:`reward_overlay_test.gd` extends SceneTree、`root.add_child(ov)`——`push_input` 可用;system_test 驱动完整宿主,同可用。 + +## 4. 设计契约(违反即返工;🔴 触碰=L3 停机呈报) + +1. 🔴 **真输入唯一通道**:所有转换一律经 `game/probe/probe_ui_util.gd` 的 `push_click`/`push_click_at`(合成 InputEvent 走 `push_input`,press+release 成对;tests 面经 preload 复用同一件,禁复制第二份合成输入件);禁回退信号直发;〔接线断言〕豁免面零新增(test-conventions §2)。 +2. 🔴 **转换零弱化**:每个转换点的既有动线断言逐条保持,落点判定(点了之后到哪个屏/哪层可见)不删、不改判;实现期发现既有断言保不住绿且非驱动问题=疑似产品缺陷浮出,停卡呈报登记,禁顺手改断言或改产品码。 +3. 🔴 **死接缝同批清**:转换后零调用的 press_* 方法与只验证旧口的护栏同批删除;禁为机检文本保留无效成员或别名(code-conventions §1.1⑤);机检键与本契约互斥时停卡呈报,不自造第三条路。 +4. 🔴 **封装边界**:产品码零私取新增(本批产品码改动仅 A2 一处容错与一个公开读口);探针/测试面读私有控件沿用现役惯例(`ap_bar._btn_stop` 同型先例在案:ui_click_probe.gd:1065);本批新增公开面仅 `LevelMapScreen.candidate_rect` 一个。 +5. 🔴 **零数值零随机面**:本批零数值改动、零 MC 跑批、零 RNG 触碰;Core 层零触碰(改动全部落在 presentation/probe/sim/tests)。 +6. 🔴 **不触画面呈现规格**:无预览图义务、无 golden 扩项——缺陷修复以现行规格与在库基线为准(test-conventions §8.2)。 + +## 5. 范围边界 + +**收件**:S1–S5(§1)。 + +**不收件与去向**: + +- A1(开局被开始层盖住):随 camp-interact 分支(0977a548)合回即消,无需新批——该分支截至写卡时尚未合回 master;合回后自动试玩对应上报自然消失,本卡不做任何动作。 +- B3(存量 996 条断言判据出处精锚):归待办清单「测试面真输入化分期与存量断言逐条精锚」条目②,本卡不碰。 +- B4(本体对账缺口 212 条)/B5(控件级零命中缺口):须人工逐条复核后再分流(真缺口立事项/假缺口豁免清单核销),本卡不预收——合回后原条目继续在册。 +- B6(自动试玩判据收紧轮):触发权与执行归用户复核轮,本卡不碰。 +- 覆盖面板 UI 改动、闸件改动(error_scan 扫描面不扩):均不做——本批只修源头,不动机检面。 + +## 6. 关联文档同步面 + +无关联文档——本批不动任何设计文档的任何陈述(A2 为容错修复,B1/B2 为测试驱动面,零设计语义变化)。能力清单(`game/tests/README.md`)归写卡段随卡同批维护(已随本卡增行,见 §9 能力行列),非实现批义务。 + +| 文档 | 关联点 | 同步义务 | +|---|---|---| +| 无关联文档 | — | — | + +## 7. 卡前·文件结构图 + +| 文件 | 职责 | 行为改动 | +|---|---|---| +| `game/presentation/views/battle_end_overlay.gd` | 终局结算框:close() 容错(A2) | 行为改动(R1) | +| `game/presentation/views/level_map_screen.gd` | 关卡地图屏:press_candidate 接缝退役、新增 candidate_rect 命中矩形读口 | 非行为改动(接缝置换,玩家可见行为零变化,R9) | +| `game/presentation/views/ap_bar_view.gd` | AP 条:press_refresh_for_probe/press_confirm_for_probe 死接缝删除 | 非行为改动(R9) | +| `game/presentation/views/curio_pick_overlay.gd` | 三选一覆盖层:press_card/press_confirm/press_continue/press_refresh 死接缝删除 | 非行为改动(R9) | +| `game/presentation/views/node_overlay.gd` | 节点停点层:press_continue 死接缝删除 | 非行为改动(R9) | +| `game/presentation/views/debug_overlay.gd` | 调试浮窗:press_apply/press_reset/press_simulate_for_probe 死接缝删除 | 非行为改动(R9) | +| `game/probe/ui_click_probe.gd` | 主 UI 探针:定型化停手段+16 处真输入转换 | 行为改动(R2/R4) | +| `game/sim/journey_player.gd` | 自动试玩:停手行为入线+8 处转换+头注通道标注更新 | 行为改动(R3) | +| `game/probe/fx_shot_probe.gd`/`ui_tune_probe.gd`/`shot_probe.gd`/`ui_probe.gd`/`t17_defer_probe.gd`/`layout_probe.gd`/`ui_struct_probe.gd` | 各 1–5 处真输入转换(③组 11 处) | 行为改动(R5/R6) | +| `game/tests/system_test.gd` | 1 处真输入转换(④组) | 行为改动(R7) | +| `game/tests/unit/presentation/reward_overlay_test.gd` | 5 处真输入转换(④组) | 行为改动(R8) | +| `game/tests/README.md` | 能力清单 3 行新增(写卡段随卡同批,已落) | 非行为改动 | + +结构图与「落位与可复用性预检」互指:标「新增」的件=candidate_rect 一个(理由与唯一落点见 §13);其余全部为「复用既有」或删除。 + +## 8. 任务卡 T1..T7 + +**T1|A2 关闭容错修复**(估时 [0.25, 0.5],中值 0.375) + +- [ ] 开工核对:§3 现状事实逐条 file:line 复核;master 若已推进致行号漂移就地校正,漂移超一屏呈报。 +- [ ] 实装:`battle_end_overlay.gd:194`(close)与 `:331`(_play_celebrate)两处同改——`get_meta(&"celebrate_tw", null)` 改 `has_meta(&"celebrate_tw")` 前置判断,有句柄才取并 kill,无句柄跳过;语义不变(有则必杀、无则无事)。 +- [ ] 验证:`…console.exe --headless --path . res://probe/fx_probe.tscn` 直跑,输出 grep「SCRIPT ERROR」与「celebrate_tw」零命中。 +- [ ] 验证:`res://probe/screen_flow_probe.tscn` 直跑,同判据零命中。 +- [ ] 读数写进本步提交信息。 + +**T2|B1 探针定型化停手段**(估时 [0.5, 1],中值 0.75) + +接口——产出:`ui_click_probe` 新增 `_stoptest_tick()`(状态机形态镜像现役 `_locktest_tick`:待命→点击→核效→完);被对照表 R2 与能力行「停手钮真输入命中与停手收轮落效」承接。 + +- [ ] 新增定型化段:每 run 一次;触发条件=战局挖掘期(行动经济相位 Active、停手钮使能、盘面未清、本 run 尚未测过);触发 tick 冻结其余随机行为,仅提交停手。 +- [ ] 驱动:`ProbeUiUtil.push_click(main, …ap_bar._btn_stop)`(与 :1065 同型)。 +- [ ] 断言①命中登记:点击后覆盖登记件停手键在场(`probe_coverage_recorder` 现役命中登记口);零命中即红(正面效力自检——防驱动中断空转假绿)。 +- [ ] 断言②落效:点击后行动经济相位离开 Active(停手收轮;本 tick 零挖掘提交,排除清图混淆)。 +- [ ] 验证:ui_click_probe 孤立直跑绿,读数入提交信息。 + +**T3|B1 自动试玩停手+journey 方法口 8 处转换**(估时 [0.75, 1.5],中值 1.125) + +接口——取用:T4 的 `LevelMapScreen.candidate_rect(index: int) -> Rect2`。产出:journey 覆盖登记含停手键。 + +- [ ] journey_player 新增停手行为:每战至多一次,条件=挖掘期(Active、停手钮使能、AP 已花 ≥1、盘面未清)时 `ProbeUiUtil.push_click` 停手钮(确定性触发,无随机占比——触发时点微调在代拍板白名单)。 +- [ ] 8 处方法口转换:`:380` → `push_click(node_overlay._btn)`;`:441` → `push_click_at(level_screen.candidate_rect(0).get_center())`;`:449`/`:457` → `push_click(curio 继续真钮——`_continue_btn`,驱动分支已按其 visible 分发)`;`:451`/`:454` → 选卡(bcard 全局矩形中心 push_click_at);`:452`/`:455` → `push_click` 确认真钮。 +- [ ] 头注(:14)「两处方法口如实标注通道」句更新为方法口清零。 +- [ ] 试车:journey 跑批 ≥2 分钟,先最小参数跑通全链(解析/落盘/登记件写出)再放全线(闸机轮次纪律)。 +- [ ] 验证:journey 全线跑批一次——读数=①覆盖登记件新增停手键与候选/停点键 ②journey_report meta 零 fatal、上报结构不变。读数入提交信息。 + +**T4|B2 ui_click_probe 16 处转换+candidate_rect 读口**(估时 [0.75, 1.25],中值 1.0) + +接口——产出:`LevelMapScreen.candidate_rect(index: int) -> Rect2`(候选命中矩形,全局坐标,命中面=同 `_candidate_at` 的节点方块面;index 越界返回空 Rect2,调用方跳过)。 + +- [ ] `level_map_screen.gd`:新增 candidate_rect(内部复用 `_cand_ids`/`_layout` 计算,矩形与 press_candidate 命中面同源);删除 press_candidate(:469-479)。 +- [ ] 候选 2 处(`:426`/`:536`)→ `push_click_at(candidate_rect(…).get_center())`。 +- [ ] 节点继续 2 处(`:448`/`:656`)→ `push_click(node_overlay._btn)`。 +- [ ] 三选一 10 处(`:473`/`:475`/`:476`/`:478`/`:479`/`:481`/`:649`/`:651`/`:652`/`:654`)→ 选卡=bcard 全局矩形中心 push_click_at;确认/继续=真钮 push_click。 +- [ ] 弃图刷新链 2 处(`:972`/`:975`)→ `push_click(_btn_refresh)`(disabled 守卫即真实拒绝路径)+`push_click(确认 chips 真钮——`_confirm_row` 内 Button 子件)`。 +- [ ] 逐处核对既有动线断言落点判定原样保持(🔴 契约 2)。 +- [ ] 验证:ui_click_probe 孤立直跑绿+覆盖登记件键集较改前不回退(新增停点链/候选/弃图确认键)。读数入提交信息。 + +**T5|B2 其余 7 探针 11 处转换**(估时 [0.5, 1],中值 0.75) + +接口——取用:T4 的 candidate_rect。 + +- [ ] 候选 6 处:`fx_shot_probe.gd:47`、`ui_tune_probe.gd:109`、`shot_probe.gd:147`、`ui_probe.gd:83`、`t17_defer_probe.gd:39`、`layout_probe.gd:32` → `push_click_at(candidate_rect(0).get_center())`。 +- [ ] 停点 1 处:`ui_struct_probe.gd:257` → `push_click(node_overlay._btn)`。 +- [ ] 调试浮窗 4 处:`ui_tune_probe.gd:59`/`:62`/`:67`/`:97` → `push_click`(对应按钮控件)。 +- [ ] `shot_probe.gd:9` 头注同步(「真实选路提交」语随形态更新)。 +- [ ] 验证:7 个探针逐件孤立直跑绿。读数入提交信息。 + +**T6|B2 非探针层 6 处转换+死接缝清理**(估时 [0.5, 0.75],中值 0.625) + +- [ ] `system_test.gd:433` → `push_click_at(candidate_rect(0).get_center())`(tests 面经 preload 复用 ProbeUiUtil)。 +- [ ] `reward_overlay_test.gd` 5 处(`:60`/`:64`/`:65`/`:66`/`:76`)→ 真输入(root 已挂树):刷新/确认/继续=对应真钮 push_click,选卡=bcard 矩形中心 push_click_at;断言语义逐位保持(三卡呈现/选择外发/强制确认两段式/结果态)。 +- [ ] 死接缝删除(全仓 grep 确认零调用后逐个删):ap_bar_view(2)、curio_pick_overlay(4)、node_overlay(1)、debug_overlay(3)、level_map_screen(press_candidate,T4 已删)。 +- [ ] 验证:系统测试直跑绿+单元与集成套件直跑绿+全仓 .gd 面双模式 grep 零命中——定义清 `func press_(candidate|continue|card|confirm|refresh|apply|reset|simulate)` 与调用清 `\.press_(candidate|continue|card|confirm|refresh|apply|reset|simulate)`(均 `--include=*.gd`,排除 reports/ 与注释外文档;`shot_probe.gd:9` 注释随 T5 同步后 .gd 面应零命中)。读数入提交信息。 + +**T7|产出物落位卡**(估时 [0.25, 0.25],中值 0.25) + +- [ ] `reports/iter-实现报告-<日期>.md`:各卡状态+实机目检总清单(本批目检项=覆盖面板控件下钻停手键与停点链键在场)+遗留读数义务+实现决定记录。 +- [ ] `reports/iter-反哺点清单-<日期>.md`:照写(本卡申报「无关联文档」,零条)。 +- [ ] 批末按改动域选档跑闸(游戏码批),里程碑步出口一次;改前改后读数对拍在案。 +- [ ] 独立验收审计入口预约:`reports/iter-验收审计-<日期>.md`(未参与实现的会话或子代理;未过不合回)。 + +## 9. 验证闸(改动—验收对照表) + +| 需求点 | 改动(文件:行/行为) | 验收测试(名称+落点+尾缀) | 层级 | 真实入口 | 判据绑定面 | 能力行 | +|---|---|---|---|---|---|---| +| `design/engineering/test-conventions.md:60` 终局结算框关闭与庆祝续播动线零引擎报错 | battle_end_overlay.gd:194(close)与 :331(_play_celebrate)两处 get_meta 缺省 null 报错 → has_meta 前置判断 | fx_probe+screen_flow_probe 孤立直跑,日志零「celebrate_tw」报错行〔QA收口 V1〕(grep 读数) | 探针 | fx_probe 真实实例化 open_victory→close→open_defeat→close 全序(两处报错点均经真实动线触达) | 探针日志零报错行。观测面局限申报:该缺陷唯一提交面=报错打印本体,无状态面可钉——静态+日志读数承载,对照表行内申报在案 | 新增:终局结算框关闭动线零引擎报错 | +| `design/engineering/test-conventions.md:23` 停手钮使能窗真输入命中与落效(探针) | ui_click_probe 新增 _stoptest_tick 定型化段 | ui_click_probe 直跑:①登记件停手键在场②相位离开 Active 收轮③零命中即红〔QA收口 V2〕 | 探针 | AP 条停手钮 push_input 真点击(使能窗内) | 覆盖登记件停手键+行动经济相位收轮(落效规格句=design/gdd/systems/排雷循环/排雷玩法.md:167 停手=玩家主动收轮、:162 批次唯一结算入口) | 新增:停手钮真输入命中与停手收轮落效 | +| `design/engineering/test-conventions.md:23` 自动试玩停手行为入线+方法口清零(S3+S4c) | journey_player 新增停手行为+8 处方法口转换(:380/441/449/451/452/454/455/457)+头注通道句更新 | journey 全线跑批:登记件停手键与候选/停点键在场+meta 零 fatal〔QA收口 V3〕 | sim | journey_player 全线跑批(sim 直跑) | journey 覆盖登记件停手键+候选/停点键+上报零 fatal | 新增:停手钮真输入命中与停手收轮落效;新增:停点链与控件级真输入命中 | +| `design/engineering/test-conventions.md:23` 停点链真输入化(ui_click_probe 16 处) | ui_click_probe.gd:426/448/473-481/536/649-656/972-975 方法口→push_input 驱动 | ui_click_probe 直跑绿+既有动线断言逐条保持(落点判定)+登记件新增对应键〔QA收口 V4〕 | 探针 | 候选矩形中心/停点真钮/三选一卡面 push_input | 既有落点断言逐条+覆盖登记件键集不回退 | 新增:停点链与控件级真输入命中 | +| `design/engineering/test-conventions.md:23` 到达型候选+停点真输入化(7 探针) | fx_shot_probe.gd:47/ui_tune_probe.gd:109/shot_probe.gd:147/ui_probe.gd:83/t17_defer_probe.gd:39/layout_probe.gd:32 → candidate_rect+push_click_at;ui_struct_probe.gd:257 → push_click(node_overlay._btn) | 7 探针各孤立直跑绿〔QA收口 V5〕 | 探针 | 候选节点矩形中心与停点真钮 push_input | 各探针既有断言保持绿+登记件候选/停点键 | 新增:停点链与控件级真输入命中 | +| `design/engineering/test-conventions.md:23` 调试浮窗面真输入化(4 处) | ui_tune_probe.gd:59/62/67/97 → push_click | ui_tune_probe 孤立直跑绿〔QA收口 V6〕 | 探针 | 调试浮窗真钮 push_input | 既有断言保持绿+登记件浮窗键 | 新增:停点链与控件级真输入命中 | +| `design/engineering/test-conventions.md:23` 系统测试宿主候选真输入化 | system_test.gd:433 → candidate_rect+真输入 | 系统测试套件直跑绿〔QA收口 V7〕 | 系统 | system_test 宿主 push_input | 既有断言保持绿 | 新增:停点链与控件级真输入命中 | +| `design/engineering/test-conventions.md:23` 三选一覆盖层单元真输入化(5 处) | reward_overlay_test.gd:60/64/65/66/76 → 真输入 | 单元与集成套件直跑绿,断言语义逐位保持〔QA收口 V8〕 | 单元 | 覆盖层 root 挂树 push_input | 既有断言逐条(三卡呈现/选择外发/强制确认两段式/结果态) | 新增:停点链与控件级真输入命中 | +| `design/engineering/test-conventions.md:52` 死接缝同批清理(5 文件 11 方法) | ap_bar_view 2+curio_pick_overlay 4+node_overlay 1+debug_overlay 3+level_map_screen 1 删除 | 全仓 .gd 面双模式 grep 零命中(定义清+调用清)〔QA收口 V9〕 | 单元 | 不适用(非行为改动——依据=转换后零调用,玩家可见行为零变化;grep 判据 .gd 面可复跑) | 全仓 .gd 面 grep(词表 candidate/continue/card/confirm/refresh/apply/reset/simulate,--include=*.gd):定义行 `func press_` 与调用行 `.press_` 各零命中(正则全文见 T6 验证步) | 新增:停点链与控件级真输入命中 | + +测试削弱申报:本批允许删除的旧断言=只验证被删 press_* 死接缝的护栏(如有)——删除随 T6 同批、逐处 grep 在案;其余既有断言零削弱。能力清单同批增行 3 行(game/tests/README.md 旅程段六:终局结算框关闭动线零引擎报错/停手钮真输入命中与停手收轮落效/停点链与控件级真输入命中)——已随卡落盘。 + +## 10. 异常分级 + +- **L1 自救(一次重试)**:探针驱动落点断言失配(矩形中心取点偏移、使能窗 tick 时机)——修驱动重跑该探针。 +- **L2 记录继续(连续 3 次同红灯升级)**:转换点在特定战局形态下偶发不命中——记录场景、缩窄触发条件后继续。 +- **L3 停机写报告等用户**:①使能窗在真实局不可达成(停手钮使能投影与相位快照永久错位)——停卡呈报;②既有断言保不住绿且非驱动问题(疑似产品缺陷浮出)——停卡登记,禁顺手修;③机检预算互斥/闸判据与本卡契约冲突——停卡退写卡段;④journey 全线跑批读数结构性变化(上报结构变、fatal 新增)——停卡呈报。 + +## 11. 代拍板白名单 + +- 断言失败消息文案与尾缀编号(〔QA收口 V1〕–〔QA收口 V9〕)分配。 +- `_stoptest_tick` 状态机 tick 上限、使能窗等待时长、触发条件的具体写法。 +- candidate_rect 矩形命中面的扩边余量(以 `_candidate_at` 命中面同源为准)。 +- journey 停手行为触发时点微调(每战至多一次框架内的具体时点)。 +- 死接缝删除的批次内顺序与头注/注释同步措辞。 + +## 12. 待裁点 + +零待裁点,开工门=U0。两个范围分叉已于 2026-11-06 由用户裁决写入:B1=探针面+自动试玩(C);B2=全清 41 处(含调试浮窗面与非探针层)。 + +## 13. 落位与可复用性预检 + +- **复用面**:真输入合成单点复用 `game/probe/probe_ui_util.gd`(push_click/push_click_at/push_wheel 现役共用面——grep 同职责实现仅此一件,tests 面经 preload 复用,禁复制第二份);覆盖登记复用 `game/probe/probe_coverage_recorder.gd`(现役命中登记口,零改动);定型化段形态复用 ui_click_probe 现役 `_locktest_tick` 状态机先例。 +- **唯一面**:本批新增公开面仅 1 个——`LevelMapScreen.candidate_rect(index: int) -> Rect2`。为什么不能复用既有:press_candidate 是「按序号提交选路」的动作口而非矩形出口,真输入点击需要命中矩形坐标;其内部 `_cand_ids`/`_layout`/`_candidate_at` 均为私有计算面——公开读口是唯一合规出口,且与命中检测同文件同源(落点唯一)。新增前已 grep:全仓无同名与同义标识符。 +- **分层与交互面**:本批零产品码新依赖——A2 为视图内容错;candidate_rect 为视图公开读口(零核心写调用,依赖方向不新增);探针/sim/tests 面改动不进任何 S 系静态扫描面(code-conventions §4.13 分档在案),其可靠性由场景探针/冒烟/单元与集成/系统测试四条运行期通道承接。 + +## 14. 禁为机检文本保留无效成员 + +本批含删除面(死接缝 11 方法)。条款:禁止为迎合机检消息文本(含计数)而保留或新增无效成员/别名;全仓 grep 零残留(T6)是删除完成的唯一判据;机检键与本契约互斥时实现段停卡呈报,不得自造第三条路。 + +## 15. 实现规范预算 + +无新增文件。存量触面一查:`level_map_screen.gd` 公开方法数=删 press_candidate(−1)+增 candidate_rect(+1)=净持平,较登记基线不升;其余 5 个视图文件只删不增(下降)。探针/sim/tests 面不在 S 系扫描面(code-conventions §4.13),无预算对账键;新写测试件全类型标注照 test-conventions §6 执行。 + +## 16. 复核记录 + +| 轮次 | 复核者身份 | 发现 | 去向 | 处置结果 | +|---|---|---|---|---| +| 1 | 只读子代理(Explore,未参与本卡撰写,2026-11-06) | F1 验收档行粗体致 C4 正则不匹配 | 补写 | 头部行去粗体,「验收档:中」冒号紧随词面(pipeline_gate.py:66) | +| 1 | 同上 | F2 journey_player.gd:449/:457 误标 node_overlay——实证 :446 `co`=curio_overlay,实为三选一继续钮 | 补写 | §3 表②与 T3 更正映射::449/:457 → curio 继续真钮;:380 保持 node_overlay._btn | +| 1 | 同上 | F3 battle_end_overlay.gd:331(_play_celebrate)同型第二处 get_meta 漏修——只修 :194 则 V1 在胜利轮仍红 | 补写 | T1 实装与 R1 扩至 :194+:331 两处同改;R1 真实入口改 open_victory→close→open_defeat→close 全序 | +| 1 | 同上 | F4 ui_struct_probe.gd:257 停点转换无对照表行承接(反向闭合缺口) | 补写 | R5 行扩为 7 探针(到达型候选+停点),改动格并入 :257 | +| 1 | 同上 | F5 V9 grep 字面命中卡自身与 shot_probe.gd:9 注释——审计复跑必红 | 补写 | V9 限定全仓 .gd 面(--include=*.gd);注释随 T5 同步清零 | +| 1 | 同上 | F6 V9 点模式抓不到定义残留(func 行无点前缀) | 补写 | V9 扩双模式:定义清+调用清各零命中 | +| 1 | 同上 | F7 R9「6 文件 11 方法」计数误(实为 5 文件) | 自判 | 改「5 文件 11 方法」(逐文件数 2/4/1/3+1=11,grep 实证) | +| 1 | 同上 | F8 R1 锚语义弱——test-conventions.md:60 为闸件条文非行为规格句,design/ 无更强句 | 自判(判定不改) | 不改+依据:缺陷修复行预期值来源=设计事实源指认的缺陷本体;:60 为「报错标记即违规」工程规范句、C5 存在性过;为日志噪声修复新立设计句不成比例 | +| 1 | 同上 | F9 两处行号微漂(ap_bar :111→:110-111;press_candidate :469-477→:469-479) | 自判 | 就地校正 | +| 1 | 同上 | C3 机检红——R9 能力行格「非行为改动(R9)」不符 CAP_ROW_RE | 补写 | R9 能力行格改「新增:停点链与控件级真输入命中」,非行为改动标记留在真实入口格(pipeline_gate.py:617-622) | +| 1 | 同上 | 引擎三查:get_meta/has_meta 报错行为「未判」(NEVER/Gotchas 无条目);push_input 成对与 Tween.kill 守卫两查成立 | 自判(不改) | T1 直跑 grep 判据可实证收口,不阻塞开工 | diff --git a/tools/capability_audit.py b/tools/capability_audit.py index 6cb4b237..9e684477 100644 --- a/tools/capability_audit.py +++ b/tools/capability_audit.py @@ -333,6 +333,12 @@ def check_coverage(cov_tables, names): def main(): + # GBK 控制台兜底(红项明细含 ✗ 等非 GBK 字符,编码崩=红项被吞不可见) + for stream in (sys.stdout, sys.stderr): + try: + stream.reconfigure(encoding="utf-8", errors="replace") + except AttributeError: + pass ap = argparse.ArgumentParser() ap.add_argument("--strict", action="store_true") args = ap.parse_args() diff --git a/tools/pipeline_gate.py b/tools/pipeline_gate.py index 0fd6c8c1..8e5aec2b 100644 --- a/tools/pipeline_gate.py +++ b/tools/pipeline_gate.py @@ -72,7 +72,6 @@ REVIEW_RULE_DATE = (2026, 11, 6) REVIEW_HEADING_RE = re.compile(r"^#{2,4}\s*\d*\.?\s*复核记录") REVIEW_TARGET_WORDS = ("自判", "补写", "待裁", "退回上游") REVIEW_HEADER_WORDS = ("轮次", "去向") -REVIEW_REPORT_RE = re.compile(r"reports/复核-[^\s()(),,、|]+\.md") # 待办条目正文限长双判据(2026-11-04 立,doc-conventions §12.1:行数抓清单蔓延、字数抓单行堆砌) ENTRY_MAX_LINES = 12 ENTRY_MAX_CHARS = 700 @@ -652,7 +651,7 @@ def check_review(lines, start, path, issues, root): """C6 复核记录的单节校验(req-card 必备结构第 17 节,生效 2026-11-06)。 只查结构与可核性:节内每条记录行都要带四类去向之一(自判/补写/待裁/退回上游), - 表格行的处置结果格(末格)非空;节内须申报 reports/复核-*.md 路径且该文件在盘上存在。 + 表格行的处置结果格(末格)非空;复核凭据=本节自身,不另设报告文件(2026-11-06 用户裁)。 分流分得对不对属语义判断,本闸不判。返回节末行下标(不含)。 """ end = len(lines) @@ -685,15 +684,6 @@ def check_review(lines, start, path, issues, root): if records == 0: issues.append((str(path), start + 1, "复核记录空节", "「复核记录」节内没有一条发现记录——卡片必经对抗复核并逐轮登记")) - sec = "\n".join(lines[start:end]) - reports = REVIEW_REPORT_RE.findall(sec) - if not reports: - issues.append((str(path), start + 1, "复核报告未申报", - "「复核记录」节末须申报复核报告落盘路径 reports/复核-<批名>-<日期>.md")) - for rel in reports: - if not (root / rel).is_file(): - issues.append((str(path), start + 1, "复核报告不可核", - "申报的复核报告不在盘上:%s" % rel)) return end diff --git a/待办清单.md b/待办清单.md index d3cc11b7..8b73f477 100644 --- a/待办清单.md +++ b/待办清单.md @@ -245,11 +245,11 @@ #### QA harness 三批缺陷与覆盖遗漏收口(2026-11-06 登记,来源=批次移交,优先级=P0) -**实况**:证据=reports/QA-harness三批-缺陷与覆盖遗漏报告-2026-11-06.md(八类逐条带文件行号与登记处指针:产品缺陷 2=A1 开局被开始层盖住/A2 终局关闭路径引擎报错噪声;测试覆盖遗漏 6=B1 停手钮零真输入/B2 视图方法面/B3 精锚/B4 本体缺口 212 条/B5 控件零命中缺口/B6 判据收紧轮);来源批次=合并 d3c85390(三批读数在案)。处置分流:A1 随营地交互修复批合回即消;A2/B1/B2 走需求性工程写卡通道;B3/B6 归衔接条目与复核轮;B4/B5 人工复核后分流(真缺口立事项/假缺口豁免清单核销)。 +**实况**:证据=reports/QA-harness三批-缺陷与覆盖遗漏报告-2026-11-06.md(八类逐条带文件行号与登记处指针:产品缺陷 2=A1 开局被开始层盖住/A2 终局关闭路径引擎报错噪声;测试覆盖遗漏 6=B1 停手钮零真输入/B2 视图方法面/B3 精锚/B4 本体缺口 212 条/B5 控件零命中缺口/B6 判据收紧轮);来源批次=合并 d3c85390(三批读数在案)。处置分流:A1 随营地交互修复批合回即消;A2/B1/B2 走需求性工程写卡通道;B3/B6 归衔接条目与复核轮;B4/B5 人工复核后分流(真缺口立事项/假缺口豁免清单核销)。需求卡片=reports/需求卡片-QA缺陷收口批-2026-11-06.md **改动面**:游戏代码 -**状态**:待写卡 +**状态**:已写卡 #### 闸机超时守卫缺陷修复——gate_run_timeout 标志文件恒真(2026-11-06 登记,来源=批次移交)