iter54-卡1:QA harness 缺陷与覆盖遗漏收口批(A2 终局结算框 has_meta 容错+B1 停手真输入探针定型段与 journey 停手行为+B2 视图方法口 41 处全清转真输入+死接缝 11 方法清理+LevelMapScreen.candidate_rect 读口)——对照表 R1-R9 全绿(fx_probe/screen_flow_probe 零报错行/ui_click_probe 问题0 覆盖生长/单元套+系统测试+82 套件 all green/双模式 grep 零命中/journey 停手键 6 次),批末 --code 六闸全绿【验收通过】无新增红
This commit is contained in:
1 parent
a2e500a4af
commit
96123978c1
19 files changed
+279
-120
No files matched your search
@@ -189,20 +189,10 @@ func is_refresh_ready() -> bool:
|
|||||||
return not _btn_refresh.disabled
|
return not _btn_refresh.disabled
|
||||||
|
|
||||||
|
|
||||||
# 探针接缝(合成输入走真实翻译出口口径):刷新按钮点击 → 确认 chips 全链路
|
|
||||||
func press_refresh_for_probe() -> void:
|
|
||||||
_on_refresh_pressed()
|
|
||||||
|
|
||||||
|
|
||||||
func confirm_visible() -> bool:
|
func confirm_visible() -> bool:
|
||||||
return _confirm_row.visible
|
return _confirm_row.visible
|
||||||
|
|
||||||
|
|
||||||
func press_confirm_for_probe() -> void:
|
|
||||||
if _arm_timer.is_armed():
|
|
||||||
_disarm_and_fire()
|
|
||||||
|
|
||||||
|
|
||||||
func refresh_remaining_text() -> String:
|
func refresh_remaining_text() -> String:
|
||||||
return _refresh_sub.text
|
return _refresh_sub.text
|
||||||
|
|
||||||
|
|||||||
@@ -191,10 +191,11 @@ func close() -> void:
|
|||||||
st.seal.visible = false
|
st.seal.visible = false
|
||||||
st.seal.modulate = Color.WHITE
|
st.seal.modulate = Color.WHITE
|
||||||
st.cele.visible = false
|
st.cele.visible = false
|
||||||
var tw: Tween = get_meta(&"celebrate_tw", null) # 循环句柄随节点存(跨 open/close,close 必杀)
|
if has_meta(&"celebrate_tw"): # 循环句柄随节点存(跨 open/close:有则必杀、无则无事——缺 meta 跳过)
|
||||||
if tw != null and tw.is_valid():
|
var tw: Tween = get_meta(&"celebrate_tw")
|
||||||
tw.kill()
|
if tw.is_valid():
|
||||||
remove_meta(&"celebrate_tw")
|
tw.kill()
|
||||||
|
remove_meta(&"celebrate_tw")
|
||||||
_clear_crest_bricks()
|
_clear_crest_bricks()
|
||||||
|
|
||||||
|
|
||||||
@@ -328,9 +329,10 @@ func _spawn_dust_mote(i: int, base: Vector2) -> void:
|
|||||||
func _play_celebrate() -> void:
|
func _play_celebrate() -> void:
|
||||||
if UiKit.motion_scale < 1.0:
|
if UiKit.motion_scale < 1.0:
|
||||||
return
|
return
|
||||||
var prev: Tween = get_meta(&"celebrate_tw", null)
|
if has_meta(&"celebrate_tw"): # 有句柄才取并 kill(缺 meta 静默跳过——败走后首次胜利同款容错)
|
||||||
if prev != null and prev.is_valid():
|
var prev: Tween = get_meta(&"celebrate_tw")
|
||||||
prev.kill()
|
if prev.is_valid():
|
||||||
|
prev.kill()
|
||||||
var tw := st.cele.create_tween()
|
var tw := st.cele.create_tween()
|
||||||
set_meta(&"celebrate_tw", tw)
|
set_meta(&"celebrate_tw", tw)
|
||||||
tw.set_loops()
|
tw.set_loops()
|
||||||
|
|||||||
@@ -153,26 +153,6 @@ func _on_confirm_pressed() -> void:
|
|||||||
pick_confirmed.emit(_selected)
|
pick_confirmed.emit(_selected)
|
||||||
|
|
||||||
|
|
||||||
# 探针/测试复用:以真实按钮路径触发点选、确认与继续(树序遮挡纪律——断言走真实信号路径)
|
|
||||||
func press_card(index: int) -> void:
|
|
||||||
# M7:卡载体 Button→bcard(gui_input 点选)——真实路径=同一 _select_card 处理器,探针语义不变
|
|
||||||
if index >= 0 and index < _card_meta.size():
|
|
||||||
_select_card(String(_card_meta[index].get("id", "")))
|
|
||||||
|
|
||||||
|
|
||||||
func press_confirm() -> void:
|
|
||||||
_confirm_btn.pressed.emit()
|
|
||||||
|
|
||||||
|
|
||||||
func press_continue() -> void:
|
|
||||||
_continue_btn.pressed.emit()
|
|
||||||
|
|
||||||
|
|
||||||
# 探针/测试复用:以真实按钮路径触发刷新意图(信号外发——受理归组合根)
|
|
||||||
func press_refresh() -> void:
|
|
||||||
_refresh_btn.pressed.emit()
|
|
||||||
|
|
||||||
|
|
||||||
# 兑付反馈态(curio_resolved 到达——结果行追加在头部之后;唯一出口 = 继续)
|
# 兑付反馈态(curio_resolved 到达——结果行追加在头部之后;唯一出口 = 继续)
|
||||||
func show_result(text: String) -> void:
|
func show_result(text: String) -> void:
|
||||||
_label.text = _header + "\n" + text
|
_label.text = _header + "\n" + text
|
||||||
|
|||||||
@@ -123,20 +123,6 @@ func output_text() -> String:
|
|||||||
return st.sim_out.get_parsed_text()
|
return st.sim_out.get_parsed_text()
|
||||||
|
|
||||||
|
|
||||||
# ---- 探针接缝(真实翻译出口——按钮 pressed 信号路径,非直调组合根)----
|
|
||||||
|
|
||||||
func press_apply_for_probe() -> void:
|
|
||||||
_apply_btn_pressed()
|
|
||||||
|
|
||||||
|
|
||||||
func press_reset_for_probe() -> void:
|
|
||||||
_reset_btn_pressed()
|
|
||||||
|
|
||||||
|
|
||||||
func press_simulate_for_probe() -> void:
|
|
||||||
_sim_btn.pressed.emit()
|
|
||||||
|
|
||||||
|
|
||||||
# ---- 内部(信号 → 外发)----
|
# ---- 内部(信号 → 外发)----
|
||||||
|
|
||||||
func _apply_btn_pressed() -> void:
|
func _apply_btn_pressed() -> void:
|
||||||
|
|||||||
@@ -465,18 +465,20 @@ func _submit_choice(nid: int) -> void:
|
|||||||
route_chosen.emit(nid)
|
route_chosen.emit(nid)
|
||||||
|
|
||||||
|
|
||||||
# 探针复用:按候选序号走图上命中同路径(候选节点中心坐标 → 命中检测 → 提交——布局决策 2 探针面改造)
|
# 探针面命中矩形读口:候选节点的图上命中矩形(全局坐标——真输入 push_click_at 落点)。
|
||||||
func press_candidate(index: int) -> void:
|
# 命中面与 _candidate_at 同源(节点方块+外扩容差);index 越界或候选未就绪返回空 Rect2(调用方跳过)。
|
||||||
|
func candidate_rect(index: int) -> Rect2:
|
||||||
if index < 0 or index >= _cand_ids.size() or _map.runner == null:
|
if index < 0 or index >= _cand_ids.size() or _map.runner == null:
|
||||||
return
|
return Rect2()
|
||||||
var nodes: Array[Variant] = _map.runner.nodes()
|
var nodes: Array[Variant] = _map.runner.nodes()
|
||||||
var node := _node_by_id(int(_cand_ids[index]), nodes)
|
var node := _node_by_id(int(_cand_ids[index]), nodes)
|
||||||
if node.is_empty():
|
if node.is_empty():
|
||||||
return
|
return Rect2()
|
||||||
var pos: Vector2 = _layout(nodes, _map.canvas)[node]
|
var pos: Vector2 = _layout(nodes, _map.canvas)[node]
|
||||||
var nid := _candidate_at(pos) # 节点中心必命中自身(命中面含节点方块)
|
var half := NODE_HALF + Vector2(HIT_PAD, HIT_PAD)
|
||||||
if nid >= 0:
|
var local := Rect2(pos - half, half * 2.0)
|
||||||
_submit_choice(nid)
|
var xform := _map.canvas.get_global_transform()
|
||||||
|
return Rect2(xform * local.position, local.size)
|
||||||
|
|
||||||
|
|
||||||
# ---- 视口锚点(布局决策 5:当前节点居中;入口停点尚无当前节点=锚入口组包围盒居中) ----
|
# ---- 视口锚点(布局决策 5:当前节点居中;入口停点尚无当前节点=锚入口组包围盒居中) ----
|
||||||
|
|||||||
@@ -29,10 +29,6 @@ func show_rest(healed: int, hp_after: int, max_hp: int) -> void:
|
|||||||
_btn.text = "休息完毕,继续"
|
_btn.text = "休息完毕,继续"
|
||||||
visible = true
|
visible = true
|
||||||
|
|
||||||
# 探针复用:以真实按钮路径触发继续
|
|
||||||
func press_continue() -> void:
|
|
||||||
_btn.pressed.emit()
|
|
||||||
|
|
||||||
|
|
||||||
func _emit_continue_pressed() -> void:
|
func _emit_continue_pressed() -> void:
|
||||||
continue_pressed.emit()
|
continue_pressed.emit()
|
||||||
@@ -45,7 +45,7 @@ func _ready() -> void:
|
|||||||
return
|
return
|
||||||
for i in 5:
|
for i in 5:
|
||||||
await get_tree().process_frame
|
await get_tree().process_frame
|
||||||
main.ui.modals.run.level_screen.press_candidate(0)
|
ProbeUiUtil.push_click_at(main, main.ui.modals.run.level_screen.candidate_rect(0).get_center())
|
||||||
for i in 20:
|
for i in 20:
|
||||||
await get_tree().process_frame
|
await get_tree().process_frame
|
||||||
var st = main.run_scope.settlement
|
var st = main.run_scope.settlement
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ func _ready() -> void:
|
|||||||
for i in range(8):
|
for i in range(8):
|
||||||
await get_tree().process_frame
|
await get_tree().process_frame
|
||||||
# 进战斗屏——三区(B 战斗画面/C 角色信息/D 扫雷图)同屏常驻,菜单屏不构成断言面
|
# 进战斗屏——三区(B 战斗画面/C 角色信息/D 扫雷图)同屏常驻,菜单屏不构成断言面
|
||||||
main.ui.modals.run.level_screen.press_candidate(0)
|
ProbeUiUtil.push_click_at(main, main.ui.modals.run.level_screen.candidate_rect(0).get_center())
|
||||||
for i in range(20):
|
for i in range(20):
|
||||||
await get_tree().process_frame
|
await get_tree().process_frame
|
||||||
for vp in VIEWPORTS:
|
for vp in VIEWPORTS:
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
# 流程 = 真实按钮信号路径驱动(ui_click_probe 同款;存档/设置/元进度三面换注隔离档——禁碰真实档,
|
# 流程 = 真实按钮信号路径驱动(ui_click_probe 同款;存档/设置/元进度三面换注隔离档——禁碰真实档,
|
||||||
# 坑册「断点写盘随 save_manager 引用走」教训同款覆盖):菜单(启动态)→ 设置面(settingsbtn
|
# 坑册「断点写盘随 save_manager 引用走」教训同款覆盖):菜单(启动态)→ 设置面(settingsbtn
|
||||||
# 真实信号路径)→ 生涯页(函数直调中间态——卡② mn10)→ 营地(进档开层新路径——mn9)→ 关卡画面(函数直调中间态→停点出图)→
|
# 真实信号路径)→ 生涯页(函数直调中间态——卡② mn10)→ 营地(进档开层新路径——mn9)→ 关卡画面(函数直调中间态→停点出图)→
|
||||||
# 战斗(level_screen.press_candidate(0) 真实选路提交)→ 状态面板(地图屏状态角标真实信号路径)。
|
# 战斗(level_screen candidate_rect 命中矩形真点选路提交)→ 状态面板(地图屏状态角标真实信号路径)。
|
||||||
# 每屏双帧 + frame_post_draw 同步后抓 get_viewport().get_texture(),PNG 落输出目录;
|
# 每屏双帧 + frame_post_draw 同步后抓 get_viewport().get_texture(),PNG 落输出目录;
|
||||||
# 最小自检 = 七件存在且非零字节(像素方差断言归 tools/shot_checker.py——B 档骨架分工)。
|
# 最小自检 = 七件存在且非零字节(像素方差断言归 tools/shot_checker.py——B 档骨架分工)。
|
||||||
# 商店房不纳屏(真实路径口径):真实路径必经 L1 打穿→L2 商店节点
|
# 商店房不纳屏(真实路径口径):真实路径必经 L1 打穿→L2 商店节点
|
||||||
@@ -149,10 +149,10 @@ func _ready() -> void:
|
|||||||
var expect := "◈ %d" % int(main.ui.modals.run.level_screen.get("_runner").gp)
|
var expect := "◈ %d" % int(main.ui.modals.run.level_screen.get("_runner").gp)
|
||||||
if gp_label.text != expect:
|
if gp_label.text != expect:
|
||||||
_problems.append("GP 徽章读数不符: %s != %s" % [gp_label.text, expect])
|
_problems.append("GP 徽章读数不符: %s != %s" % [gp_label.text, expect])
|
||||||
# ④ 战斗(节点一——真实选路提交路径 press_candidate,ui_click_probe :199 同款)
|
# ④ 战斗(节点一——candidate_rect 命中矩形真点选路提交,ui_click_probe 同款)
|
||||||
# oracle: design/gdd/ux/battle.md:122 B 区构建:站桩/明细带/轮次指示(战斗出图与几何锚组)
|
# oracle: design/gdd/ux/battle.md:122 B 区构建:站桩/明细带/轮次指示(战斗出图与几何锚组)
|
||||||
if main.ui.modals.run.level_screen != null and main.ui.modals.run.level_screen.visible:
|
if main.ui.modals.run.level_screen != null and main.ui.modals.run.level_screen.visible:
|
||||||
main.ui.modals.run.level_screen.press_candidate(0)
|
ProbeUiUtil.push_click_at(main, main.ui.modals.run.level_screen.candidate_rect(0).get_center())
|
||||||
for i in 10:
|
for i in 10:
|
||||||
await get_tree().process_frame
|
await get_tree().process_frame
|
||||||
await _snap("battle")
|
await _snap("battle")
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ func _ready() -> void:
|
|||||||
return
|
return
|
||||||
for i in 5:
|
for i in 5:
|
||||||
await get_tree().process_frame
|
await get_tree().process_frame
|
||||||
main.ui.modals.run.level_screen.press_candidate(0)
|
ProbeUiUtil.push_click_at(main, main.ui.modals.run.level_screen.candidate_rect(0).get_center())
|
||||||
for i in 20:
|
for i in 20:
|
||||||
await get_tree().process_frame
|
await get_tree().process_frame
|
||||||
if main.run_scope.settlement == null:
|
if main.run_scope.settlement == null:
|
||||||
|
|||||||
@@ -40,6 +40,8 @@ var _route_clicks := 0 # 选路覆盖层点击计数(岔路使用
|
|||||||
var _locktest_state := 0 # T1 D1 锁期/重放断言状态机(0=待注入 1=等重放 2=完结)——每 run 一次
|
var _locktest_state := 0 # T1 D1 锁期/重放断言状态机(0=待注入 1=等重放 2=完结)——每 run 一次
|
||||||
var _locktest_cell := Vector2i(-9, -9)
|
var _locktest_cell := Vector2i(-9, -9)
|
||||||
var _locktest_frames := 0
|
var _locktest_frames := 0
|
||||||
|
var _stoptest_state := 0 # 停手钮定型化覆盖段状态机(0=待命 1=已点击待核效 2=完结)——每 run 一次
|
||||||
|
var _stoptest_frames := 0
|
||||||
|
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
@@ -421,13 +423,13 @@ func _ready() -> void:
|
|||||||
var wc3_txt: String = main.ui.battle.log_view._log.get_parsed_text()
|
var wc3_txt: String = main.ui.battle.log_view._log.get_parsed_text()
|
||||||
if not wc3_txt.contains("种子 42") or not wc3_txt.contains("(含面板加成)"):
|
if not wc3_txt.contains("种子 42") or not wc3_txt.contains("(含面板加成)"):
|
||||||
_problems.append("开场行回归失守:局外加成(pct>0)局的开场行应带「(含面板加成)」(wc3)")
|
_problems.append("开场行回归失守:局外加成(pct>0)局的开场行应带「(含面板加成)」(wc3)")
|
||||||
# 关卡开始 = 入口选路停点——press_candidate 图上命中路径选入口候选进首战
|
# 关卡开始 = 入口选路停点——candidate_rect 命中矩形中心真点选入口候选进首战
|
||||||
#(首格可点 AC 口径随之含入口选路一步:菜单点击 → 停点呈现 → pick → 棋盘安装)
|
#(首格可点 AC 口径随之含入口选路一步:菜单点击 → 停点呈现 → pick → 棋盘安装)
|
||||||
if main.ui.modals.run.level_screen.visible:
|
if main.ui.modals.run.level_screen.visible:
|
||||||
# 独立性断言:独立屏激活期战斗屏宿主整体隐藏
|
# 独立性断言:独立屏激活期战斗屏宿主整体隐藏
|
||||||
if main.ui.screens.battle_root.visible:
|
if main.ui.screens.battle_root.visible:
|
||||||
_problems.append("独立屏激活期战斗屏宿主未隐藏(零透出契约失守)")
|
_problems.append("独立屏激活期战斗屏宿主未隐藏(零透出契约失守)")
|
||||||
main.ui.modals.run.level_screen.press_candidate(0)
|
ProbeUiUtil.push_click_at(main, main.ui.modals.run.level_screen.candidate_rect(0).get_center())
|
||||||
await get_tree().process_frame
|
await get_tree().process_frame
|
||||||
await get_tree().process_frame
|
await get_tree().process_frame
|
||||||
var t_entry := Time.get_ticks_msec() - t1
|
var t_entry := Time.get_ticks_msec() - t1
|
||||||
@@ -449,7 +451,7 @@ func _ready() -> void:
|
|||||||
action_budget -= 1
|
action_budget -= 1
|
||||||
await get_tree().process_frame
|
await get_tree().process_frame
|
||||||
if main.ui.modals.run.node_overlay.visible:
|
if main.ui.modals.run.node_overlay.visible:
|
||||||
main.ui.modals.run.node_overlay.press_continue()
|
ProbeUiUtil.push_click(main, main.ui.modals.run.node_overlay._btn)
|
||||||
_seals_placed.clear()
|
_seals_placed.clear()
|
||||||
continue
|
continue
|
||||||
if main.ui.modals.run.curio_overlay.visible:
|
if main.ui.modals.run.curio_overlay.visible:
|
||||||
@@ -474,15 +476,17 @@ func _ready() -> void:
|
|||||||
if not main.ui.flow.locks_input():
|
if not main.ui.flow.locks_input():
|
||||||
_problems.append("三选一停点打开时输入未锁定")
|
_problems.append("三选一停点打开时输入未锁定")
|
||||||
if main.ui.modals.run.curio_overlay._continue_btn.visible:
|
if main.ui.modals.run.curio_overlay._continue_btn.visible:
|
||||||
main.ui.modals.run.curio_overlay.press_continue()
|
ProbeUiUtil.push_click(main, main.ui.modals.run.curio_overlay._continue_btn)
|
||||||
elif main.run_scope.adventure != null and not main.run_scope.adventure.stop()._node_pending.is_empty():
|
elif main.run_scope.adventure != null and not main.run_scope.adventure.stop()._node_pending.is_empty():
|
||||||
main.ui.modals.run.curio_overlay.press_card(0) # 奖励节点待选态:点首件+确认(真实按钮信号路径——与关卡完成停点同形)
|
ProbeUiUtil.push_click_at(main, (main.ui.modals.run.curio_overlay._bcards[0] as Control).get_global_rect().get_center()) # 奖励节点待选态:真点首卡+确认(gui_input 点选——与关卡完成停点同形)
|
||||||
main.ui.modals.run.curio_overlay.press_confirm()
|
await get_tree().process_frame # 选卡当帧确认钮才现形、容器重排在途——排版帧后矩形成形再真点
|
||||||
|
ProbeUiUtil.push_click(main, main.ui.modals.run.curio_overlay._confirm_btn)
|
||||||
elif main.run_scope.adventure != null and not main.run_scope.adventure.stop()._pending.is_empty():
|
elif main.run_scope.adventure != null and not main.run_scope.adventure.stop()._pending.is_empty():
|
||||||
main.ui.modals.run.curio_overlay.press_card(0)
|
ProbeUiUtil.push_click_at(main, (main.ui.modals.run.curio_overlay._bcards[0] as Control).get_global_rect().get_center())
|
||||||
main.ui.modals.run.curio_overlay.press_confirm()
|
await get_tree().process_frame # 同上:确认钮排版帧
|
||||||
|
ProbeUiUtil.push_click(main, main.ui.modals.run.curio_overlay._confirm_btn)
|
||||||
else:
|
else:
|
||||||
main.ui.modals.run.curio_overlay.press_continue() # 停点已消费的残面——继续关屏
|
ProbeUiUtil.push_click(main, main.ui.modals.run.curio_overlay._continue_btn) # 停点已消费的残面——继续关屏
|
||||||
_seals_placed.clear()
|
_seals_placed.clear()
|
||||||
continue
|
continue
|
||||||
if main.ui.modals.menu.shop_overlay.visible:
|
if main.ui.modals.menu.shop_overlay.visible:
|
||||||
@@ -537,7 +541,7 @@ func _ready() -> void:
|
|||||||
if String(nd.get("type", "")) == "reward" and main.ui.modals.run.level_screen._cand_ids.has(nd_id):
|
if String(nd.get("type", "")) == "reward" and main.ui.modals.run.level_screen._cand_ids.has(nd_id):
|
||||||
pick = main.ui.modals.run.level_screen._cand_ids.find(nd_id)
|
pick = main.ui.modals.run.level_screen._cand_ids.find(nd_id)
|
||||||
break
|
break
|
||||||
main.ui.modals.run.level_screen.press_candidate(pick)
|
ProbeUiUtil.push_click_at(main, main.ui.modals.run.level_screen.candidate_rect(pick).get_center())
|
||||||
_route_clicks += 1
|
_route_clicks += 1
|
||||||
_seals_placed.clear()
|
_seals_placed.clear()
|
||||||
continue
|
continue
|
||||||
@@ -626,11 +630,13 @@ func _ready() -> void:
|
|||||||
_ap_spent_this_round = 0
|
_ap_spent_this_round = 0
|
||||||
_last_state = st
|
_last_state = st
|
||||||
_locktest_tick()
|
_locktest_tick()
|
||||||
|
_stoptest_tick()
|
||||||
if main.run_scope.settlement.battle_result == "" and main.run_scope.settlement.action_economy.phase == "Active":
|
if main.run_scope.settlement.battle_result == "" and main.run_scope.settlement.action_economy.phase == "Active":
|
||||||
# T1 D1——锁测在飞期(state 1)冻结探针动作面:排空帧 autoplay 的免费 move 会抢在
|
# T1 D1——锁测在飞期(state 1)冻结探针动作面:排空帧 autoplay 的免费 move 会抢在
|
||||||
# 帧末 deferred 重放之前改变英雄位(seal 拒收 not_adjacent 实证)——「注入→重放」
|
# 帧末 deferred 重放之前改变英雄位(seal 拒收 not_adjacent 实证)——「注入→重放」
|
||||||
# 窗口内局面零变化正是 v3.1 被测语义(演播期冻结),动作面恢复待断言收口。
|
# 窗口内局面零变化正是 v3.1 被测语义(演播期冻结),动作面恢复待断言收口。
|
||||||
if _locktest_state != 1:
|
# 停手定型化段同款冻结:核效窗口内零挖掘提交,排除 AP/盘面漂移对收轮判据的混淆。
|
||||||
|
if _locktest_state != 1 and _stoptest_state != 1:
|
||||||
_run_modal_probes_once()
|
_run_modal_probes_once()
|
||||||
_play_one_action()
|
_play_one_action()
|
||||||
# ---- 预算耗尽收口(T17 硬锁批适配):选件变强后 probe 可能活过预算不再战败——断点段前提
|
# ---- 预算耗尽收口(T17 硬锁批适配):选件变强后 probe 可能活过预算不再战败——断点段前提
|
||||||
@@ -651,14 +657,15 @@ func _ready() -> void:
|
|||||||
break
|
break
|
||||||
elif main.ui.modals.run.curio_overlay.visible:
|
elif main.ui.modals.run.curio_overlay.visible:
|
||||||
if main.ui.modals.run.curio_overlay._continue_btn.visible:
|
if main.ui.modals.run.curio_overlay._continue_btn.visible:
|
||||||
main.ui.modals.run.curio_overlay.press_continue()
|
ProbeUiUtil.push_click(main, main.ui.modals.run.curio_overlay._continue_btn)
|
||||||
elif main.run_scope.adventure != null and not main.run_scope.adventure.stop()._pending.is_empty():
|
elif main.run_scope.adventure != null and not main.run_scope.adventure.stop()._pending.is_empty():
|
||||||
main.ui.modals.run.curio_overlay.press_card(0)
|
ProbeUiUtil.push_click_at(main, (main.ui.modals.run.curio_overlay._bcards[0] as Control).get_global_rect().get_center())
|
||||||
main.ui.modals.run.curio_overlay.press_confirm()
|
await get_tree().process_frame # 选卡当帧确认钮才现形、容器重排在途——排版帧后矩形成形再真点
|
||||||
|
ProbeUiUtil.push_click(main, main.ui.modals.run.curio_overlay._confirm_btn)
|
||||||
else:
|
else:
|
||||||
main.ui.modals.run.curio_overlay.press_continue()
|
ProbeUiUtil.push_click(main, main.ui.modals.run.curio_overlay._continue_btn)
|
||||||
elif main.ui.modals.run.node_overlay.visible:
|
elif main.ui.modals.run.node_overlay.visible:
|
||||||
main.ui.modals.run.node_overlay.press_continue()
|
ProbeUiUtil.push_click(main, main.ui.modals.run.node_overlay._btn)
|
||||||
elif main.ui.modals.menu.shop_overlay.visible:
|
elif main.ui.modals.menu.shop_overlay.visible:
|
||||||
var shop_leave2: Button = ProbeUiUtil.find_button(main.ui.modals.menu.shop_overlay, "离开商店")
|
var shop_leave2: Button = ProbeUiUtil.find_button(main.ui.modals.menu.shop_overlay, "离开商店")
|
||||||
if shop_leave2 != null:
|
if shop_leave2 != null:
|
||||||
@@ -978,10 +985,13 @@ func _run_modal_probes_once() -> void:
|
|||||||
_tested_refresh_chain = true
|
_tested_refresh_chain = true
|
||||||
var rap_before: int = int(main.run_scope.settlement.action_economy.rap)
|
var rap_before: int = int(main.run_scope.settlement.action_economy.rap)
|
||||||
var board_before = main.run_scope.settlement.minesweeper.current_board()
|
var board_before = main.run_scope.settlement.minesweeper.current_board()
|
||||||
main.ui.battle.board_zone.ap_bar.press_refresh_for_probe()
|
ProbeUiUtil.push_click(main, main.ui.battle.board_zone.ap_bar._btn_refresh) # 真点弃图刷新(disabled 守卫=真实拒绝路径)
|
||||||
if not main.ui.battle.board_zone.ap_bar.confirm_visible():
|
if not main.ui.battle.board_zone.ap_bar.confirm_visible():
|
||||||
_problems.append("弃图刷新确认 chips 未出现(异位确认缺失)")
|
_problems.append("弃图刷新确认 chips 未出现(异位确认缺失)")
|
||||||
main.ui.battle.board_zone.ap_bar.press_confirm_for_probe()
|
for c in main.ui.battle.board_zone.ap_bar._confirm_row.get_children():
|
||||||
|
if c is Button:
|
||||||
|
ProbeUiUtil.push_click(main, c) # 真点确认 chips 真钮(异位确认——_confirm_row 内 Button 子件)
|
||||||
|
break
|
||||||
if int(main.run_scope.settlement.action_economy.rap) != rap_before - 8:
|
if int(main.run_scope.settlement.action_economy.rap) != rap_before - 8:
|
||||||
_problems.append("弃图刷新未扣 RAP8(%d→%d)" % [rap_before, int(main.run_scope.settlement.action_economy.rap)])
|
_problems.append("弃图刷新未扣 RAP8(%d→%d)" % [rap_before, int(main.run_scope.settlement.action_economy.rap)])
|
||||||
if main.run_scope.settlement.action_economy.phase != "Active":
|
if main.run_scope.settlement.action_economy.phase != "Active":
|
||||||
@@ -1155,6 +1165,56 @@ func _locktest_pick_cell(minesweeper) -> Vector2i:
|
|||||||
return Vector2i(-1, -1)
|
return Vector2i(-1, -1)
|
||||||
|
|
||||||
|
|
||||||
|
# ---- 停手钮定型化覆盖段(B1——每 run 一次:使能窗内真点停手钮,钉命中登记与收轮落效) ----
|
||||||
|
# 触发条件=战局挖掘期(相位 Active+停手钮使能+盘面有挖可走+本 run 未测过);触发帧冻结
|
||||||
|
# 自动玩家其余随机行为,仅提交停手(驱动与 _click_stop 同型——AP 条真钮 push_input)。
|
||||||
|
# 断言两钉:①覆盖登记件停手键在场(零命中=驱动空转假绿,即红);②相位离开 Active(停手
|
||||||
|
# 收轮)。前提消失守卫:点击后战局收场(终结演播竞态)→ 静默弃测不计 problem(正常局不触发)。
|
||||||
|
func _stoptest_tick() -> void:
|
||||||
|
# oracle: design/gdd/systems/排雷循环/排雷玩法.md:167 (停手=玩家主动收轮——判定上报通道)
|
||||||
|
if _stoptest_state == 2:
|
||||||
|
return
|
||||||
|
var settlement = main.run_scope.settlement
|
||||||
|
if settlement == null or settlement.minesweeper == null or settlement.minesweeper.current_board() == null:
|
||||||
|
return
|
||||||
|
if _stoptest_state == 0:
|
||||||
|
if String(settlement.battle_result) != "" or main.ui.modals.run.end_overlay.is_open():
|
||||||
|
return # 战局已收场——本 run 无停手窗(静置)
|
||||||
|
if not main.ui.screens.row_pacer.pending_rows().is_empty():
|
||||||
|
return # 演播期不出手:点击会进锁期缓存被吞(同 _locktest_tick 前提)
|
||||||
|
var ae = settlement.action_economy
|
||||||
|
if String(ae.phase) != "Active" or int(ae.ap) < 1:
|
||||||
|
return
|
||||||
|
var stop_btn: Button = main.ui.battle.board_zone.ap_bar._btn_stop
|
||||||
|
if stop_btn == null or stop_btn.disabled:
|
||||||
|
return # 停手钮未使能——下帧重试
|
||||||
|
if AutoPlayer.choose_dig(settlement.minesweeper).is_empty():
|
||||||
|
return # 盘面已无可挖——不算挖掘期触发窗(防清图混淆)
|
||||||
|
_stoptest_state = 1
|
||||||
|
_stoptest_frames = 0
|
||||||
|
_click_stop()
|
||||||
|
elif _stoptest_state == 1:
|
||||||
|
_stoptest_frames += 1
|
||||||
|
if _stoptest_frames > 120:
|
||||||
|
_problems.append("停手定型化段:点击后 120 帧相位仍 Active(收轮落效失守)〔QA收口 V2〕")
|
||||||
|
_stoptest_state = 2
|
||||||
|
return
|
||||||
|
if String(settlement.battle_result) != "" or main.ui.modals.run.end_overlay.is_open():
|
||||||
|
_stoptest_state = 2 # 前提消失守卫:终结演播竞态——静默弃测
|
||||||
|
return
|
||||||
|
if String(settlement.action_economy.phase) != "Active":
|
||||||
|
_stoptest_assert_hit()
|
||||||
|
_stoptest_state = 2
|
||||||
|
|
||||||
|
|
||||||
|
func _stoptest_assert_hit() -> void:
|
||||||
|
# oracle: design/gdd/systems/排雷循环/排雷玩法.md:167 (停手钮真输入命中登记——判定上报通道)
|
||||||
|
var stop_btn: Button = main.ui.battle.board_zone.ap_bar._btn_stop
|
||||||
|
var stop_key := String(_recorder._node_keys.get(stop_btn.get_instance_id(), ""))
|
||||||
|
if stop_key == "" or not _recorder._hits.has(stop_key):
|
||||||
|
_problems.append("停手定型化段:停手钮真点零命中登记(驱动空转假绿)〔QA收口 V2〕")
|
||||||
|
|
||||||
|
|
||||||
func _report_stall(st: Dictionary) -> void:
|
func _report_stall(st: Dictionary) -> void:
|
||||||
# oracle: design/engineering/test-conventions.md:30 (判定上报通道——验证函数组)
|
# oracle: design/engineering/test-conventions.md:30 (判定上报通道——验证函数组)
|
||||||
var why := ""
|
var why := ""
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ func _ready() -> void:
|
|||||||
await get_tree().process_frame
|
await get_tree().process_frame
|
||||||
await get_tree().process_frame
|
await get_tree().process_frame
|
||||||
# ---- 入口选路停点(关卡开始即出节点图——level_started 后、首战前弹选路层;
|
# ---- 入口选路停点(关卡开始即出节点图——level_started 后、首战前弹选路层;
|
||||||
# press_candidate 图上命中路径 pick 入口单候选进首战)----
|
# candidate_rect 命中矩形真点 pick 入口单候选进首战)----
|
||||||
# oracle: design/gdd/ux/level-map.md:11 入口停点候选数=入口个数(入口单候选断言)
|
# oracle: design/gdd/ux/level-map.md:11 入口停点候选数=入口个数(入口单候选断言)
|
||||||
# ---- 独立性断言(独立屏激活期战斗屏宿主整体隐藏,零透出)----
|
# ---- 独立性断言(独立屏激活期战斗屏宿主整体隐藏,零透出)----
|
||||||
if not main.ui.modals.run.level_screen.visible:
|
if not main.ui.modals.run.level_screen.visible:
|
||||||
@@ -86,7 +86,7 @@ func _ready() -> void:
|
|||||||
or main.run_scope.runner.next_candidate_ids().size() != 1:
|
or main.run_scope.runner.next_candidate_ids().size() != 1:
|
||||||
problems.append("入口停点状态失守(选路态 + 入口单候选)")
|
problems.append("入口停点状态失守(选路态 + 入口单候选)")
|
||||||
else:
|
else:
|
||||||
main.ui.modals.run.level_screen.press_candidate(0)
|
ProbeUiUtil.push_click_at(main, main.ui.modals.run.level_screen.candidate_rect(0).get_center())
|
||||||
await get_tree().process_frame
|
await get_tree().process_frame
|
||||||
await get_tree().process_frame
|
await get_tree().process_frame
|
||||||
if not main.ui.screens.battle_root.visible or main.ui.modals.run.level_screen.visible:
|
if not main.ui.screens.battle_root.visible or main.ui.modals.run.level_screen.visible:
|
||||||
|
|||||||
@@ -272,7 +272,7 @@ func _ready() -> void:
|
|||||||
if not main.ui.modals.run.node_overlay.visible:
|
if not main.ui.modals.run.node_overlay.visible:
|
||||||
problems.append("[node] 节点结算层未打开(rest 兑付路径中断)")
|
problems.append("[node] 节点结算层未打开(rest 兑付路径中断)")
|
||||||
await _audit("node_overlay", [main.ui.modals.run.node_overlay])
|
await _audit("node_overlay", [main.ui.modals.run.node_overlay])
|
||||||
main.ui.modals.run.node_overlay.press_continue()
|
ProbeUiUtil.push_click(main, main.ui.modals.run.node_overlay._btn)
|
||||||
_settle()
|
_settle()
|
||||||
if main.ui.modals.run.node_overlay.visible:
|
if main.ui.modals.run.node_overlay.visible:
|
||||||
problems.append("[node] 关闭后层未隐藏(continue_pressed 路径中断)")
|
problems.append("[node] 关闭后层未隐藏(continue_pressed 路径中断)")
|
||||||
|
|||||||
@@ -58,16 +58,47 @@ func _ready() -> void:
|
|||||||
problems.append("生效预览未联动(%s)" % main.ui.modals.menu.debug_overlay.effect_text())
|
problems.append("生效预览未联动(%s)" % main.ui.modals.menu.debug_overlay.effect_text())
|
||||||
# ③ 应用(真实信号路径:apply_requested → 组合根)——E4 后加成零表写,生效断言移至 ⑧ 战斗快照
|
# ③ 应用(真实信号路径:apply_requested → 组合根)——E4 后加成零表写,生效断言移至 ⑧ 战斗快照
|
||||||
# oracle: design/engineering/test-conventions.md:49 调试面加成链路:滑条联动/应用/重置、hero 表运行期只读(②③④⑦组)
|
# oracle: design/engineering/test-conventions.md:49 调试面加成链路:滑条联动/应用/重置、hero 表运行期只读(②③④⑦组)
|
||||||
main.ui.modals.menu.debug_overlay.press_apply_for_probe()
|
var apply_btn: Button = ProbeUiUtil.find_button(main.ui.modals.menu.debug_overlay, "应用并关闭")
|
||||||
|
if apply_btn == null:
|
||||||
|
problems.append("调试浮窗「应用并关闭」钮缺失")
|
||||||
|
else:
|
||||||
|
ProbeUiUtil.push_click(main, apply_btn) # 真点应用(组合根应用=关浮窗——落点断言由 ④ 重开承载)
|
||||||
# ④ 重置(重开浮窗 → 重置按钮真实路径;面板百分比归零——下一场战斗生效值回到基线)
|
# ④ 重置(重开浮窗 → 重置按钮真实路径;面板百分比归零——下一场战斗生效值回到基线)
|
||||||
main._show_debug_overlay()
|
main._show_debug_overlay()
|
||||||
main.ui.modals.menu.debug_overlay.press_reset_for_probe()
|
var reset_btn: Button = ProbeUiUtil.find_button(main.ui.modals.menu.debug_overlay, "重置为 0")
|
||||||
|
if reset_btn == null:
|
||||||
|
problems.append("调试浮窗「重置为 0」钮缺失")
|
||||||
|
else:
|
||||||
|
ProbeUiUtil.push_click(main, reset_btn)
|
||||||
# ⑤ 批量模拟全链路(N=10——走 level_autoplay 与 headless 扫描同口径;表基线由组合根复位;
|
# ⑤ 批量模拟全链路(N=10——走 level_autoplay 与 headless 扫描同口径;表基线由组合根复位;
|
||||||
# 菜单态上下文未锁定=按钮可点,is_running 语义=模拟在跑〔18卡⑦ 与对局禁用态拆分〕)
|
# 菜单态上下文未锁定=按钮可点,is_running 语义=模拟在跑〔18卡⑦ 与对局禁用态拆分〕)
|
||||||
# oracle: design/engineering/test-conventions.md:49 调试面批量模拟链路:N=10 输出关卡完成率/剩余 HP/败北节点(⑤组)
|
# oracle: design/engineering/test-conventions.md:49 调试面批量模拟链路:N=10 输出关卡完成率/剩余 HP/败北节点(⑤组)
|
||||||
main.ui.modals.menu.debug_overlay.set_sliders(100, 0)
|
main.ui.modals.menu.debug_overlay.set_sliders(100, 0)
|
||||||
main.ui.modals.menu.debug_overlay.set_sim_count(10)
|
main.ui.modals.menu.debug_overlay.set_sim_count(10)
|
||||||
main.ui.modals.menu.debug_overlay.press_simulate_for_probe()
|
# 折叠区控件真输入通道(test-conventions §2——先滚轮滚入可视区再点):sim 钮在滚动列表 boot
|
||||||
|
# 滚位下跨出视口底边(rect y=639 对 scroll 底 641、钮高 40——hit 面被裁),真点必落空;
|
||||||
|
# 滚轮下探滚入可视区后真点(实证一档入视口、同帧 is_running 翻真)
|
||||||
|
var sim_btn: Button = main.ui.modals.menu.debug_overlay._sim_btn
|
||||||
|
var sim_scroll: ScrollContainer = null
|
||||||
|
var sim_stack: Array = [main.ui.modals.menu.debug_overlay]
|
||||||
|
while not sim_stack.is_empty():
|
||||||
|
var sn: Node = sim_stack.pop_back()
|
||||||
|
if sn is ScrollContainer:
|
||||||
|
sim_scroll = sn
|
||||||
|
break
|
||||||
|
for sch in sn.get_children():
|
||||||
|
sim_stack.append(sch)
|
||||||
|
if sim_scroll == null:
|
||||||
|
problems.append("调试浮窗滚动列表缺失(sim 钮滚入通道无载体)")
|
||||||
|
else:
|
||||||
|
for i in 12:
|
||||||
|
if sim_scroll.get_global_rect().encloses(sim_btn.get_global_rect()):
|
||||||
|
break
|
||||||
|
ProbeUiUtil.push_wheel(main, sim_scroll.get_global_rect().get_center(), 1)
|
||||||
|
await get_tree().process_frame
|
||||||
|
if not sim_scroll.get_global_rect().encloses(sim_btn.get_global_rect()):
|
||||||
|
problems.append("sim 钮滚轮滚入可视区失败(12 档未入——折叠区真输入通道断)")
|
||||||
|
ProbeUiUtil.push_click(main, sim_btn) # 真点「运行模拟」(菜单态未锁可点——disabled 守卫=真实拒绝路径)
|
||||||
var guard := SIM_GUARD_FRAMES
|
var guard := SIM_GUARD_FRAMES
|
||||||
while main.ui.modals.menu.debug_overlay.is_running() and guard > 0:
|
while main.ui.modals.menu.debug_overlay.is_running() and guard > 0:
|
||||||
guard -= 1
|
guard -= 1
|
||||||
@@ -97,7 +128,12 @@ func _ready() -> void:
|
|||||||
# isolate_save 先删后建——上次运行的残留断点会触发互斥确认早退)
|
# isolate_save 先删后建——上次运行的残留断点会触发互斥确认早退)
|
||||||
ProbeUiUtil.isolate_save(main, "smoke_tune_probe_save", true, false, true) # 末参=swap_save(卡②签名换代——断点写盘经 autoload 落隔离档)
|
ProbeUiUtil.isolate_save(main, "smoke_tune_probe_save", true, false, true) # 末参=swap_save(卡②签名换代——断点写盘经 autoload 落隔离档)
|
||||||
main.ui.modals.menu.debug_overlay.set_sliders(100, 50)
|
main.ui.modals.menu.debug_overlay.set_sliders(100, 50)
|
||||||
main.ui.modals.menu.debug_overlay.press_apply_for_probe()
|
main._show_debug_overlay() # ⑥ 关闭后重开——⑧ 应用真点(应用=组合根关窗,⑧b 显式关浮窗断言照旧承载)
|
||||||
|
var apply_btn2: Button = ProbeUiUtil.find_button(main.ui.modals.menu.debug_overlay, "应用并关闭")
|
||||||
|
if apply_btn2 == null:
|
||||||
|
problems.append("调试浮窗「应用并关闭」钮缺失(⑧)")
|
||||||
|
else:
|
||||||
|
ProbeUiUtil.push_click(main, apply_btn2)
|
||||||
main.ui.modals.menu.debug_overlay.seed_edit.text = "42" # 种子钉死(18卡⑦审计🔴——空框=非首局随机,显式优先经真实路径断言 master_seed)
|
main.ui.modals.menu.debug_overlay.seed_edit.text = "42" # 种子钉死(18卡⑦审计🔴——空框=非首局随机,显式优先经真实路径断言 master_seed)
|
||||||
main._start_adventure_from_menu() # 完整冒险路径(唯一试玩入口;_start_single 按语义清零滑条 = 恒基线,不承载加成断言)
|
main._start_adventure_from_menu() # 完整冒险路径(唯一试玩入口;_start_single 按语义清零滑条 = 恒基线,不承载加成断言)
|
||||||
await get_tree().process_frame
|
await get_tree().process_frame
|
||||||
@@ -107,9 +143,9 @@ func _ready() -> void:
|
|||||||
problems.append("开冒险路径未显式关浮窗(T2 防护失守)")
|
problems.append("开冒险路径未显式关浮窗(T2 防护失守)")
|
||||||
if int(main.run_scope.adventure.master_seed) != 42:
|
if int(main.run_scope.adventure.master_seed) != 42:
|
||||||
problems.append("显式种子未达冒险(master_seed=%s ≠ 42——真实路径显式优先失守)" % str(main.run_scope.adventure.master_seed))
|
problems.append("显式种子未达冒险(master_seed=%s ≠ 42——真实路径显式优先失守)" % str(main.run_scope.adventure.master_seed))
|
||||||
# 关卡开始 = 入口选路停点——真实按钮路径选入口候选进首战再读呈现快照
|
# 关卡开始 = 入口选路停点——candidate_rect 命中矩形真点选入口候选进首战再读呈现快照
|
||||||
if main.ui.modals.run.level_screen.visible:
|
if main.ui.modals.run.level_screen.visible:
|
||||||
main.ui.modals.run.level_screen.press_candidate(0)
|
ProbeUiUtil.push_click_at(main, main.ui.modals.run.level_screen.candidate_rect(0).get_center())
|
||||||
await get_tree().process_frame
|
await get_tree().process_frame
|
||||||
await get_tree().process_frame
|
await get_tree().process_frame
|
||||||
var hero: Dictionary = main.run_scope.settlement.presentation_snapshot().hero
|
var hero: Dictionary = main.run_scope.settlement.presentation_snapshot().hero
|
||||||
|
|||||||
+42
-16
@@ -10,9 +10,9 @@
|
|||||||
# 真实输入-场景热点/真实输入-键盘/方法-地图命中口/方法-棋盘口)。原归因制度残骸=本结构内字段。
|
# 真实输入-场景热点/真实输入-键盘/方法-地图命中口/方法-棋盘口)。原归因制度残骸=本结构内字段。
|
||||||
# 误报收敛:误报指纹(类+段+归因摘要)落 .gates/coverage/journey_misfire_ledger.json——同一指纹
|
# 误报收敛:误报指纹(类+段+归因摘要)落 .gates/coverage/journey_misfire_ledger.json——同一指纹
|
||||||
# 第 2 次起自动登记静默(计数照记、不再进上报清单);连 3 批零真缺陷判据收紧归用户复核轮。
|
# 第 2 次起自动登记静默(计数照记、不再进上报清单);连 3 批零真缺陷判据收紧归用户复核轮。
|
||||||
# 驱动纪律:按钮/场景物件全走真输入(push_input 管线,同探针判据——ProbeUiUtil 单点通道)。
|
# 驱动纪律:按钮/场景物件/地图候选全走真输入(push_input 管线,同探针判据——ProbeUiUtil 单点通道;
|
||||||
# 两处方法口如实标注通道:地图候选=press_candidate(自绘布局命中路径,探针族既定入口);
|
# 地图候选=LevelMapScreen.candidate_rect 命中矩形中心 push_click_at——方法口已清零)。
|
||||||
# 棋盘格=click_cell(BoardView 公共点击口,ui_input_probe 先例——棋盘管线面由该探针承载)。
|
# 棋盘格=click_cell(BoardView 公共点击口,ui_input_probe 先例——棋盘管线面由该探针承载)=余下唯一方法口。
|
||||||
# 停点分发的视图内部读数(_continue_btn/_node_pending 等)沿用探针族直读受控例外(iter53 反哺点 9 同款在册)。
|
# 停点分发的视图内部读数(_continue_btn/_node_pending 等)沿用探针族直读受控例外(iter53 反哺点 9 同款在册)。
|
||||||
# 运行:Godot_console.exe --headless --path . res://sim/journey_player.tscn
|
# 运行:Godot_console.exe --headless --path . res://sim/journey_player.tscn
|
||||||
extends Node
|
extends Node
|
||||||
@@ -41,6 +41,10 @@ var _map_status_done := false # 地图屏状态角标一次性
|
|||||||
var _legend_done := false # 图例开合一次性(每战斗面一次)
|
var _legend_done := false # 图例开合一次性(每战斗面一次)
|
||||||
var _status_done := false # 战斗屏状态面板一次性
|
var _status_done := false # 战斗屏状态面板一次性
|
||||||
var _refresh_done := false # 刷新确认链一次性
|
var _refresh_done := false # 刷新确认链一次性
|
||||||
|
var _stop_done := false # 停手行为一次性(每战至多一次——挖掘期确定性触发)
|
||||||
|
var _stop_settlement: Variant = null # 停手基线战局(换战局重置一次性)
|
||||||
|
var _stop_round := -1 # 停手轮次基线(轮换重置已花计数)
|
||||||
|
var _digs_this_round := 0 # 本轮已提交挖掘数(停手条件——AP 已花 ≥1)
|
||||||
|
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
@@ -376,11 +380,11 @@ func _phase_adventure() -> void:
|
|||||||
_record_screens()
|
_record_screens()
|
||||||
var st := _screen_state()
|
var st := _screen_state()
|
||||||
if bool(st["节点"]):
|
if bool(st["节点"]):
|
||||||
_last_action = "节点层「继续」(方法-视图口)"
|
_last_action = "真点节点层「继续」钮"
|
||||||
main.ui.modals.run.node_overlay.press_continue()
|
ProbeUiUtil.push_click(main, main.ui.modals.run.node_overlay._btn)
|
||||||
continue
|
continue
|
||||||
if bool(st["三选一"]):
|
if bool(st["三选一"]):
|
||||||
_drive_curio()
|
await _drive_curio()
|
||||||
continue
|
continue
|
||||||
if bool(st["商店"]):
|
if bool(st["商店"]):
|
||||||
var lv: Button = ProbeUiUtil.find_button(main.ui.modals.menu.shop_overlay, "离开商店")
|
var lv: Button = ProbeUiUtil.find_button(main.ui.modals.menu.shop_overlay, "离开商店")
|
||||||
@@ -437,30 +441,42 @@ func _drive_map_once() -> void:
|
|||||||
var resumed: Button = ProbeUiUtil.find_button(main.ui.modals.run.status_panel, "继续", "prefix")
|
var resumed: Button = ProbeUiUtil.find_button(main.ui.modals.run.status_panel, "继续", "prefix")
|
||||||
if resumed != null and main.ui.modals.run.status_panel.visible:
|
if resumed != null and main.ui.modals.run.status_panel.visible:
|
||||||
ProbeUiUtil.push_click(main, resumed)
|
ProbeUiUtil.push_click(main, resumed)
|
||||||
_last_action = "地图候选命中(方法-地图命中口)"
|
_last_action = "地图候选命中(真实输入-命中矩形)"
|
||||||
main.ui.modals.run.level_screen.press_candidate(0)
|
ProbeUiUtil.push_click_at(main, main.ui.modals.run.level_screen.candidate_rect(0).get_center())
|
||||||
|
|
||||||
|
|
||||||
func _drive_curio() -> void:
|
func _drive_curio() -> void:
|
||||||
# 三选一停点:待选态点首件+确认;兑付/已消费态点继续(方法-视图口——curio 停点既定驱动面)
|
# 三选一停点:待选态真点首卡+确认(gui_input 点选——确认钮现形当帧容器重排在途,排版帧后再点);
|
||||||
|
# 兑付/已消费态真点继续
|
||||||
var co: Control = main.ui.modals.run.curio_overlay
|
var co: Control = main.ui.modals.run.curio_overlay
|
||||||
_last_action = "三选一停点分发(方法-视图口)"
|
_last_action = "三选一停点分发(真输入)"
|
||||||
if co._continue_btn.visible:
|
if co._continue_btn.visible:
|
||||||
co.press_continue()
|
ProbeUiUtil.push_click(main, co._continue_btn)
|
||||||
elif main.run_scope.adventure != null and not main.run_scope.adventure.stop()._node_pending.is_empty():
|
elif main.run_scope.adventure != null and not main.run_scope.adventure.stop()._node_pending.is_empty():
|
||||||
co.press_card(0)
|
ProbeUiUtil.push_click_at(main, (co._bcards[0] as Control).get_global_rect().get_center())
|
||||||
co.press_confirm()
|
await _frames(2)
|
||||||
|
ProbeUiUtil.push_click(main, co._confirm_btn)
|
||||||
elif main.run_scope.adventure != null and not main.run_scope.adventure.stop()._pending.is_empty():
|
elif main.run_scope.adventure != null and not main.run_scope.adventure.stop()._pending.is_empty():
|
||||||
co.press_card(0)
|
ProbeUiUtil.push_click_at(main, (co._bcards[0] as Control).get_global_rect().get_center())
|
||||||
co.press_confirm()
|
await _frames(2)
|
||||||
|
ProbeUiUtil.push_click(main, co._confirm_btn)
|
||||||
else:
|
else:
|
||||||
co.press_continue()
|
ProbeUiUtil.push_click(main, co._continue_btn)
|
||||||
|
|
||||||
|
|
||||||
func _drive_battle_once() -> void:
|
func _drive_battle_once() -> void:
|
||||||
# 战斗单步:挂死检测+功能钮真点(图例/状态/刷新确认链/停手)+棋盘挖格(方法-棋盘口)
|
# 战斗单步:挂死检测+功能钮真点(图例/状态/刷新确认链/停手)+棋盘挖格(方法-棋盘口)
|
||||||
var settlement = main.run_scope.settlement
|
var settlement = main.run_scope.settlement
|
||||||
var diag: Dictionary = settlement.diagnostic_snapshot()
|
var diag: Dictionary = settlement.diagnostic_snapshot()
|
||||||
|
if settlement != _stop_settlement: # 换战局——停手一次性与轮内计数重置
|
||||||
|
_stop_settlement = settlement
|
||||||
|
_stop_done = false
|
||||||
|
_stop_round = -1
|
||||||
|
_digs_this_round = 0
|
||||||
|
var round_now := int(diag.round)
|
||||||
|
if round_now != _stop_round:
|
||||||
|
_stop_round = round_now
|
||||||
|
_digs_this_round = 0
|
||||||
var st := {
|
var st := {
|
||||||
"round": diag.round, "phase": diag.action_economy.phase, "ap": diag.action_economy.ap,
|
"round": diag.round, "phase": diag.action_economy.phase, "ap": diag.action_economy.ap,
|
||||||
"revealed": diag.minesweeper_revealed,
|
"revealed": diag.minesweeper_revealed,
|
||||||
@@ -514,6 +530,15 @@ func _drive_battle_once() -> void:
|
|||||||
# 棋盘动作(方法-棋盘口——BoardView 公共点击口,ui_input_probe 先例;C 的按钮面全走真输入)
|
# 棋盘动作(方法-棋盘口——BoardView 公共点击口,ui_input_probe 先例;C 的按钮面全走真输入)
|
||||||
var minesweeper = settlement.minesweeper
|
var minesweeper = settlement.minesweeper
|
||||||
var plan: Dictionary = AutoPlayer.choose_dig(minesweeper)
|
var plan: Dictionary = AutoPlayer.choose_dig(minesweeper)
|
||||||
|
# 停手行为(每战至多一次——挖掘期确定性触发,无随机占比;触发时点微调在代拍板白名单):
|
||||||
|
# 相位 Active+停手钮使能+AP 已花 ≥1+盘面有挖可走 → 真点停手钮收轮(真输入行为之一)
|
||||||
|
if not _stop_done and String(diag.action_economy.phase) == "Active" \
|
||||||
|
and not ap_bar._btn_stop.disabled and _digs_this_round >= 1 and not plan.is_empty():
|
||||||
|
_stop_done = true
|
||||||
|
_last_action = "真点「停手」钮(挖掘期定型化触发)"
|
||||||
|
ProbeUiUtil.push_click(main, ap_bar._btn_stop)
|
||||||
|
await _frames(2)
|
||||||
|
return
|
||||||
if plan.is_empty():
|
if plan.is_empty():
|
||||||
plan = AutoPlayer.gamble_pick(minesweeper)
|
plan = AutoPlayer.gamble_pick(minesweeper)
|
||||||
if plan.is_empty():
|
if plan.is_empty():
|
||||||
@@ -525,6 +550,7 @@ func _drive_battle_once() -> void:
|
|||||||
if plan.hero_cell != minesweeper.hero_pos():
|
if plan.hero_cell != minesweeper.hero_pos():
|
||||||
main.ui.battle.board_zone.board_view.click_cell(plan.hero_cell, MOUSE_BUTTON_LEFT)
|
main.ui.battle.board_zone.board_view.click_cell(plan.hero_cell, MOUSE_BUTTON_LEFT)
|
||||||
main.ui.battle.board_zone.board_view.click_cell(plan.dig_cell, MOUSE_BUTTON_LEFT)
|
main.ui.battle.board_zone.board_view.click_cell(plan.dig_cell, MOUSE_BUTTON_LEFT)
|
||||||
|
_digs_this_round += 1
|
||||||
await _frames(1)
|
await _frames(1)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
extends SceneTree
|
extends SceneTree
|
||||||
|
|
||||||
const AutoPlayer := preload("res://sim/auto_player.gd") # 自动玩家策略单一实现(lifecycle 活战斗驱动;smoke 库件迁移期按现路径 preload)
|
const AutoPlayer := preload("res://sim/auto_player.gd") # 自动玩家策略单一实现(lifecycle 活战斗驱动;smoke 库件迁移期按现路径 preload)
|
||||||
|
const ProbeUiUtil := preload("res://probe/probe_ui_util.gd") # 真输入合成单点(tests 面复用共用件——禁复制第二份合成输入件)
|
||||||
|
|
||||||
var _failures: int = 0
|
var _failures: int = 0
|
||||||
var _checks: int = 0
|
var _checks: int = 0
|
||||||
@@ -436,8 +437,8 @@ func _smoke_lifecycle_matrix() -> void:
|
|||||||
await process_frame
|
await process_frame
|
||||||
await _stage_faces(main, "V3b 开局停点", "alive", "alive", "null",
|
await _stage_faces(main, "V3b 开局停点", "alive", "alive", "null",
|
||||||
{"mf_start": false, "level_vis": true})
|
{"mf_start": false, "level_vis": true})
|
||||||
# 阶段③地图选路→战斗中(真实选路提交 press_candidate)
|
# 阶段③地图选路→战斗中(真实选路提交——candidate_rect 命中矩形真点)
|
||||||
main.ui.modals.run.level_screen.press_candidate(0)
|
ProbeUiUtil.push_click_at(main, main.ui.modals.run.level_screen.candidate_rect(0).get_center())
|
||||||
for i in range(10):
|
for i in range(10):
|
||||||
await process_frame
|
await process_frame
|
||||||
await _stage_faces(main, "V3c 战斗中", "alive", "alive", "alive", {"mf_start": false})
|
await _stage_faces(main, "V3c 战斗中", "alive", "alive", "alive", {"mf_start": false})
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ extends SceneTree
|
|||||||
# 运行:godot --headless --path game --script res://tests/unit/presentation/reward_overlay_test.gd(expect 0)
|
# 运行:godot --headless --path game --script res://tests/unit/presentation/reward_overlay_test.gd(expect 0)
|
||||||
# 断言走 test_kit 计数(Kit.check)+ 失败即停早退协议(顺序状态机——坏态下后继断言无效)。
|
# 断言走 test_kit 计数(Kit.check)+ 失败即停早退协议(顺序状态机——坏态下后继断言无效)。
|
||||||
const Kit := preload("res://tests/unit/test_kit.gd")
|
const Kit := preload("res://tests/unit/test_kit.gd")
|
||||||
|
const ProbeUiUtil := preload("res://probe/probe_ui_util.gd") # 真输入合成单点(tests 面复用共用件——禁复制第二份合成输入件)
|
||||||
|
|
||||||
# 断言 + 失败即停(原直写 print FAIL + quit(1) + return 样板单点化——早退语义逐位保持)
|
# 断言 + 失败即停(原直写 print FAIL + quit(1) + return 样板单点化——早退语义逐位保持)
|
||||||
func _req(desc: String, ok: bool) -> bool:
|
func _req(desc: String, ok: bool) -> bool:
|
||||||
@@ -60,13 +61,15 @@ func _run() -> void:
|
|||||||
if not _req("付费档余额可付:免费位 0 但钮点亮(对齐商店——GP 档可刷)",
|
if not _req("付费档余额可付:免费位 0 但钮点亮(对齐商店——GP 档可刷)",
|
||||||
ov._refresh_btn.visible and not ov._refresh_btn.disabled):
|
ov._refresh_btn.visible and not ov._refresh_btn.disabled):
|
||||||
return
|
return
|
||||||
ov.press_refresh()
|
await process_frame # 刷新钮现形当帧容器重排在途——排版帧后矩形成形再真点
|
||||||
if not _req("press_refresh 未外发 refresh_requested", refreshed.size() == 1):
|
ProbeUiUtil.push_click(root, ov._refresh_btn) # 真点刷新钮(disabled 守卫=真实拒绝路径)
|
||||||
|
if not _req("真点刷新未外发 refresh_requested", refreshed.size() == 1):
|
||||||
return
|
return
|
||||||
# ② 点选→高亮→确认外发(真实按钮路径);确认前改选以最后点选为准
|
# ② 点选→高亮→确认外发(真输入管线:bcard gui_input 点选——与 press_card 同一 _select_card 处理器);确认前改选以最后点选为准
|
||||||
ov.press_card(0)
|
ProbeUiUtil.push_click_at(root, (ov._bcards[0] as Control).get_global_rect().get_center())
|
||||||
ov.press_card(1)
|
ProbeUiUtil.push_click_at(root, (ov._bcards[1] as Control).get_global_rect().get_center())
|
||||||
ov.press_confirm()
|
await process_frame # 确认钮现形当帧容器重排在途——排版帧后矩形成形再真点
|
||||||
|
ProbeUiUtil.push_click(root, ov._confirm_btn)
|
||||||
if not _req("点选确认未外发 pick_confirmed(gp)(%s)" % str(picked),
|
if not _req("点选确认未外发 pick_confirmed(gp)(%s)" % str(picked),
|
||||||
ov._confirm_btn.visible and picked.size() == 1 and String(picked[0]) == "gp"):
|
ov._confirm_btn.visible and picked.size() == 1 and String(picked[0]) == "gp"):
|
||||||
return
|
return
|
||||||
@@ -76,7 +79,8 @@ func _run() -> void:
|
|||||||
if not _req("结果态应点亮继续且收三卡与刷新钮",
|
if not _req("结果态应点亮继续且收三卡与刷新钮",
|
||||||
ov._continue_btn.visible and not ov._choice_box.visible and not ov._refresh_btn.visible):
|
ov._continue_btn.visible and not ov._choice_box.visible and not ov._refresh_btn.visible):
|
||||||
return
|
return
|
||||||
ov.press_continue()
|
await process_frame # 继续钮现形当帧容器重排在途——排版帧后矩形成形再真点
|
||||||
|
ProbeUiUtil.push_click(root, ov._continue_btn)
|
||||||
if not _req("继续未外发 continue_pressed", continued.size() == 1):
|
if not _req("继续未外发 continue_pressed", continued.size() == 1):
|
||||||
return
|
return
|
||||||
ov.close_pick()
|
ov.close_pick()
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
# 迭代 54 反哺点清单(2026-11-07)
|
||||||
|
|
||||||
|
> 本清单逐卡增量落笔;用户在会话中裁决后由文档批写入 `design/` 并把该条清掉(AGENTS 红线:实现批禁写 `design/`,迭代实现报告与反哺点归 `reports/`)。
|
||||||
|
|
||||||
|
## 卡 1|QA harness 缺陷与覆盖遗漏收口批——申报:零条
|
||||||
|
|
||||||
|
卡 1 §6 申报「无关联文档」——A2 为容错修复、B1/B2 为测试驱动面,零设计语义变化。核过面:`design/gdd/systems/排雷循环/排雷玩法.md`(停手语义句 :162/:167 与实装一致)、`design/engineering/test-conventions.md`(真输入管线条文 §2 与实装一致)——两处无需改句。
|
||||||
|
|
||||||
|
## 卡 2|营地交互修复批——(随卡 2 推进补齐)
|
||||||
|
|
||||||
|
## 卡 3|精英专属池——(随卡 3 推进补齐)
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
# 迭代 54 实现报告(2026-11-07)
|
||||||
|
|
||||||
|
> 三卡:QA harness 缺陷与覆盖遗漏收口批 → 营地交互修复批 → 精英专属池。本报告随各卡末卡增量落笔(卡 1 QA 收口段先行,卡 2/卡 3 段随后补齐),总收口前为完整版。
|
||||||
|
> 独立验收审计入口预约:`reports/iter54-验收审计-2026-11-07.md`(未参与实现的只读会话/子代理执行,未过不合回)。审计深度:卡 1=中档(对照表逐行全量、最窄复跑省略以远端 CI 现查代证);卡 2=中档;卡 3=高档(全量)。
|
||||||
|
|
||||||
|
## 卡 1|QA harness 缺陷与覆盖遗漏收口批——状态:已完成
|
||||||
|
|
||||||
|
### 各任务卡状态
|
||||||
|
|
||||||
|
| 任务卡 | 状态 | 摘要 |
|
||||||
|
|---|---|---|
|
||||||
|
| T1 A2 关闭容错修复 | 完成 | battle_end_overlay.gd close(:194) 与 _play_celebrate(:331) 两处 `get_meta(&"celebrate_tw", null)` 改 `has_meta` 前置判断,语义不变(有则必杀、无则无事)〔提交 57f3cc75〕 |
|
||||||
|
| T2 B1 探针定型化停手段 | 完成 | ui_click_probe 新增 `_stoptest_tick` 状态机(镜像 `_locktest_tick` 形态)+`_stoptest_assert_hit`,挖掘期触发窗真点停手钮,断言①覆盖登记停手键在场②相位离开 Active〔提交 816aaae5〕 |
|
||||||
|
| T3 B1 journey 停手+S4c 8 处转换 | 完成 | journey_player 新增停手行为(每战至多一次,挖掘期确定性触发)+8 处真输入转换+头注方法口句换代〔提交 2f5c734e〕 |
|
||||||
|
| T4 B2 ui_click_probe 16 处+candidate_rect | 完成 | LevelMapScreen 删 press_candidate 增 candidate_rect(index)->Rect2(命中面与 _candidate_at 同源,全局坐标,越界空 Rect2);ui_click_probe 候选 2+节点继续 2+三选一 10+弃图刷新链 2 全转真输入,既有落点断言逐条原样〔提交 afcfbf37〕 |
|
||||||
|
| T5 B2 其余 7 探针 11 处 | 完成 | 候选 6+停点 1+调试浮窗 4;shot_probe 头注同步〔提交 22903043〕 |
|
||||||
|
| T6 B2 非探针层 6 处+死接缝清理 | 完成 | system_test 1 处+reward_overlay_test 5 处真输入;死接缝 11 方法删除(ap_bar_view 2+curio_pick_overlay 4+node_overlay 1+debug_overlay 3,level_map_screen 1 随 T4)〔提交 710df6ce〕 |
|
||||||
|
| T7 产出物落位 | 完成 | 本报告+反哺点清单+批末选档跑闸(读数见下)+审计入口预约 |
|
||||||
|
|
||||||
|
### 实际对照表(R1–R9,补「结果」格)
|
||||||
|
|
||||||
|
| 行 | 验收测试 | 结果 |
|
||||||
|
|---|---|---|
|
||||||
|
| R1 终局结算框关闭动线零引擎报错 | fx_probe+screen_flow_probe 直跑 grep「SCRIPT ERROR」「celebrate_tw」 | 绿——两探针各 exit=0、SCRIPT ERROR 0、celebrate_tw 0(提交 57f3cc75 读数) |
|
||||||
|
| R2 停手钮真输入命中与落效 | ui_click_probe 直跑(_stoptest_tick 断言①②) | 绿——exit=0、问题=0、覆盖落盘停手键命中 1 次(确定性触发实证;提交 816aaae5 读数) |
|
||||||
|
| R3 journey 停手+方法口清零 | journey 全线跑批 | 绿(读数判据满足)——fatal 0、上报结构不变(2 条=已知缺陷 A1 双指纹,改前基线同源)、覆盖登记停手键 6 次+停点键在场(结算面继续 6/确认 3)、屏到达 16 类含战斗/终局;exit=1 为 A1 基线态(营地交互修复批承接中,本卡不做动作——卡 1 §5 范围边界) |
|
||||||
|
| R4 停点链真输入化(ui_click_probe 16 处) | ui_click_probe 直跑+既有落点断言+登记键集不回退 | 绿——exit=0、问题=0、覆盖 43 命中/30 控件较改前 39/28 不回退、新增停点链键(curio 确认选择 2/继续 2)、冒险终局在案选路口点击 9 次 |
|
||||||
|
| R5 到达型候选+停点(7 探针) | 7 探针逐件孤立直跑 | 绿——headless 五件(ui_struct/layout/ui_probe/t17_defer/ui_tune)exit=0+SCRIPT ERROR 0;窗口化两件(shot 七屏 PNG 齐、fx_shot PASS 演出帧 7 张挖格 3)exit=0 |
|
||||||
|
| R6 调试浮窗面(4 处) | ui_tune_probe 直跑 | 绿——PASS 全链路(含模拟 N=10 输出与种子三分断言) |
|
||||||
|
| R7 系统测试宿主候选真输入化 | 系统测试直跑 | 绿——69 项检查 0 失败、三闸过(V3c 阶段真实选路提交在跑批中执行) |
|
||||||
|
| R8 三选一覆盖层单元真输入化 | 单元与集成套件直跑 | 绿——82 套件 all green、exit=0、0 FAIL(reward_verify 断言在册) |
|
||||||
|
| R9 死接缝同批清理(5 文件 11 方法) | 全仓 .gd 双模式 grep | 绿——定义清 `func press_(candidate\|continue\|card\|confirm\|refresh\|apply\|reset\simulate)` 与调用清 `.press_(…)` 双零命中 |
|
||||||
|
|
||||||
|
### 卡 1 批末选档跑闸读数(T7)
|
||||||
|
|
||||||
|
`bash tools/run_all_gates.sh --code`(游戏码批选档)=**【验收通过】闸况与基线一致,无新增红**。回执六闸全绿:冒烟测试(smoke_boot.log)=绿/单元与集成测试(unit.log)=绿/系统测试(system_test.log)=绿/场景探针(probe.log)=绿/渲染闸(render.log)=绿/静态扫描(static_scan.log)=绿。改前改后对拍:改前基线=master 40a3ac12 远端 CI run 99 绿;改后=本跑批无新增红(闸况与基线一致)。
|
||||||
|
|
||||||
|
### 实机目检总清单(卡 1)
|
||||||
|
|
||||||
|
| 目检项 | 登记处 | 义务口径 |
|
||||||
|
|---|---|---|
|
||||||
|
| 覆盖面板控件下钻停手键与停点链键在场 | 本表(数据面读数:probe_hits_ui_click.js 停手 1 次、停点链键在案) | 真人检测只登记不阻塞(AGENTS 红线)——登记即完成义务 |
|
||||||
|
|
||||||
|
### 遗留读数义务(卡 1)
|
||||||
|
|
||||||
|
- 无 MC/verifier 义务(本卡零数值零随机面)。
|
||||||
|
- 远端 CI 现查读数(合回后):审计与追绿按 process-conventions §1 第 3 条按需现查。
|
||||||
|
|
||||||
|
### 实现决定记录(卡 1,超白名单事项备案)
|
||||||
|
|
||||||
|
1. **reward_overlay_test.gd 五处行号就地校正**:卡面申报 :60/:64/:65/:66/:76,实查为 :63/:67/:68/:69/:79(漂移 +3,内容与描述全一致)——依卡内 T1 开工核对条款就地校正,未呈报(漂移远小于一屏)。
|
||||||
|
2. **ui_click_probe 停手段与 system_test 行号就地校正**:停手触发/驱动 :1041-1045/:1063-1065 → 实查 :1051-1055/:1074-1077;system_test :433 → :440。同上依据。
|
||||||
|
3. **排版帧插入**:三选一选卡→确认之间、reward_overlay_test 刷新/确认/继续点击前、journey _drive_curio 卡→确认之间插入 1–2 帧等待——确认钮/继续钮现形当帧容器重排在途,矩形未成形真点必落空。属驱动机制细节(白名单「使能窗等待时长、触发条件的具体写法」同族)。
|
||||||
|
4. **ui_tune ⑤ sim 真点的折叠区滚轮通道**:初跑发现 sim 钮真点落空——根因=滚动列表 boot 滚位下钮矩形跨出 ScrollContainer 视口底边(hit 面被裁;emit 路径历史性掩盖)。按 test-conventions §2「折叠区控件先以真输入滚轮滚入可视区再点」落滚轮通道(一档滚入实证后定装),并配 12 档上限+滚入失败 problem 上报(正面效力自检)。⑧ 应用前置重开浮窗(同款机制先例=④ 重开浮窗)。属真输入通道的实现形态(卡片白名单「具体写法」族),随提交留痕。
|
||||||
|
5. **候选/bcard 覆盖登记键的结构性缺口**:覆盖登记件自动登记通道=BaseButton pressed+营地自绘物件两源;地图画布与 BCard 非 BaseButton、无 pressed 信号,真输入命中不产键(登记件零改动——卡 1 §13 申报)。候选/弃图确认键的对照表括注预期键与登记件能力不符:效力由既有落点断言承载(R4 判据绑定面=既有落点断言逐条+键集不回退,两者均成立)。弃图确认链在 ui_click_probe 受 is_refresh_ready(RAP≥8)门槛四种子未触发——改前同门槛不可达,链面真输入效力由 journey 既有真点链承载。此为观测面局限申报,非缺陷。
|
||||||
|
6. **T2 断言①的登记件读取形态**:`_stoptest_assert_hit` 经 `_recorder._node_keys`/`_recorder._hits` 直读登记件命中表(登记件为探针共用面、卡 1 §13 申报零改动——不新增公开读口,探针面读私有沿现役惯例:ap_bar._btn_stop 同型先例)。
|
||||||
|
7. **卡 2 T4.4「等用户发令再走收口」与迭代单合并语义的冲突处置**:卡 2 写卡时为独立批(编入迭代 54 前),其末卡收口语义已被编排段换代为迭代级总收口(iter 技能第 5 步:一次合并、五步登记)。本批按迭代级收口执行,不逐卡等发令;此冲突为编排换代遗留,随本报告呈报。
|
||||||
|
|
||||||
|
## 卡 2|营地交互修复批——状态:进行中
|
||||||
|
|
||||||
|
(随卡 2 任务卡推进补齐。)
|
||||||
|
|
||||||
|
## 卡 3|精英专属池——状态:待开工
|
||||||
|
|
||||||
|
(随卡 3 任务卡推进补齐。)
|
||||||
Reference in new issue
Block a user