并 master 7ed648da 进 camp-noon-20261106

This commit is contained in:
DKChan committed 2026-11-06 19:23:58 +08:00
commit 83cae72789
7 files changed
+588 -4

No files matched your search

+1 -1
View File
@@ -395,7 +395,7 @@
- **交付形态**:**背景层 1 张(不透明全幅)+ 围墙层 1 张 + 八个物件层 = 10 张**,其中 9 张透明底、1 张不透明全幅 + 一份坐标表(贴图矩形/命中矩形/z 序)。背景层由**远景片 `bg_far`(2560×734)与地面片 `bg_floor`(2560×866)两片出图、按 y734 拼成一张**——整张一次出图时模型把远山挤到画面下半部,被围墙挡住后完全消失(实测三张里两张山体上缘落在墙顶以下)。接缝整条落在围墙背后,画面无接缝。**篝火例外**:命中矩形只取下半(火堆),上半(火焰)只作特效展示。围墙层落盘按细条裁,不做全幅(全幅约 3.9 MB 显存,细条约 0.35 MB);**实装落盘矩形 `(0, 203, 1280, 164)`、底锚 y367**(桩身 150px、门柱 164px 终稿锁定值,落带内〔围墙带 (0,203,1280,164)〕)。
- **色彩与氛围依据**:营地的暖由晒白的地面、木色物件与烛光黄承载,安全温馨,与冒险中的地下城形成对比;远景=正午强日照——天空晴蓝、远山随距离转淡蓝灰、草地与土路晒白,整体淡而退后,近景暖调为主。现行口径 = 本文件 §2.8「全作最暖」(管菜单容器与元进度,不约束背景天空)与本节「情绪与色域」条。本节不复述色值;新增环境色按 §4.1 场景环境子板条款登记(每屏一套、≤32 色、过 §4.2 语义检查与 RGB 三通道差 ≥8/255 两道门)。
- **交互四态(零新素材,全部程序化)**:悬停=**轮廓亮边 + 浮动**(浮动须整像素吸附);按下=位移 1px;**禁用/未解锁=降明度 + 去饱和**(§2 已缩窄至情绪域,状态表达不受限),**仅锻炉(锻造工坊)与宝箱(秘宝匣)两件会有此态**;已解锁=常态。
- **钥石余额**:常驻画面顶部的一行小 HUD 栏(高 48px,**浮层覆盖,不挤压画面**)。
- **钥石余额**:常驻画面顶部的一行小 HUD 栏(高 48px,**浮层覆盖,不挤压画面**)。栏体底=`CAMP_HEADER_BAND` `#6E4526`(§7.2 五 token 对齐表在册色)× 不透明度 0.80;栏内只钥石徽章一件、右位顶格,左位不放件。呈现定值的唯一事实源=[camp](../gdd/ux/camp.md) §顶栏,本节不复述判据。验收:目检〈顶栏成一条可辨窄带,徽章落在带内〉
- **事实源边界**:解锁条件/价格/存档写入归元进度 GDD 与 `MetaProgression`;素材命名与路径归 `asset-path-map`;清单登记归 `art-assets-checklist` §3.5。
- **已裁(2026-11-01 用户裁)**:① **营地环境子板色值**——不前置拍板:量化场景实际用色后按 §4.1 场景环境子板条款登记(每屏一套、≤32 色、过 §4.2 语义检查与 RGB 三通道差 ≥8/255 两道门);② **门扇与门洞的高宽比例**——门扇贴图 240×138(锁定 240×147),随门洞 y283–367 压扁重画,坐标按门洞 x520–760 对齐;③ **帐篷的落地尺寸**——251×170 落位 (982, 335),上端遮住围墙下部。
@@ -87,7 +87,7 @@ HUD框架站在玩家与全部玩法系统之间:挖掘期它是输入的翻
| toast | 非模态 | 自动消退 2.5 秒,不打断挖掘 |
| 图例面板 / 明细回看 / 胜负终局 | 模态 | 同一张登记序栈:统一入栈出栈、后开置顶、关闭逐层恢复 |
两条纪律横跨两族。其一,"第一次遇到"类提示(本作没有双击快开、挖不相邻格要先走近)走 toast,每场冒险至多弹一次。其二,拒绝反馈不属于一次性族——每次被拒都要可感知,且图标与文案双通道冗余(不靠颜色单独承载);棋盘面拒绝(动作不合棋盘规则,目标格边框闪)与资源面拒绝(行动点或储备不足,数字脉冲)必须可区分。图例面板恒可随时打开回看,不设解锁门。
三条纪律横跨两族。其一,"第一次遇到"类提示(本作没有双击快开、挖不相邻格要先走近)走 toast,每场冒险至多弹一次。其二,拒绝反馈不属于一次性族——每次被拒都要可感知,且图标与文案双通道冗余(不靠颜色单独承载);棋盘面拒绝(动作不合棋盘规则,目标格边框闪)与资源面拒绝(行动点或储备不足,数字脉冲)必须可区分。图例面板恒可随时打开回看,不设解锁门。其三,**确认弹窗的按钮位次定值**:推进操作的钮在左、维持现状的钮(取消/留下/否)在右,三钮形态的次推进钮居中;全项目确认弹窗共用同一件、同一序,四处消费方(删档确认/营地大门有断点的三出口/营地大门无断点是否开局/篝火离场)皆然。**位次不随文案变**,语义由文案承担。
### 呈现层订阅纪律:界面不自持状态、订阅面只留两条线
+2 -2
View File
@@ -1,6 +1,6 @@
# 营地场景 UX spec(camp)
> 状态:v2.7(现行)
> 状态:v2.8(现行)
> 事实源:本 spec(呈现)+ [元进度](../systems/跨局循环/元进度.md)(机制)
> 美术画法:[art-bible](../../art/art-bible.md) §6.2/§7.5;素材命名与路径:[asset-path-map](../../art/asset-path-map.md)
> 相邻:[level-map.md](level-map.md)(主菜单语境)
@@ -38,7 +38,7 @@
## 顶栏
钥石余额常驻画面顶部一行小 HUD 栏(高 48px、全宽窄条、**浮层覆盖在场景图上层,不挤压画面**)。刷新入口已实装=营地刷新单口(进档与营地内写口尾触发,现开界面与顶栏余额同步取现值)。
钥石余额常驻画面顶部一行小 HUD 栏:高 48px、全宽窄条、**浮层覆盖在场景图上层,不挤压画面**。栏体底=营地头带深棕 `#6E4526`(token `CAMP_HEADER_BAND`,色值出处 [art-bible](../../art/art-bible.md) §7.2 五 token 对齐表)× **不透明度 0.80**——半透明系定值,底下画面透出 20%。栏内**只放钥石徽章一件**,右位、顶格落座(徽章自高 48px=栏高,无顶距可言),左位不放件。验收:目检〈顶栏成一条可辨窄带、徽章落在带内〉+机检〈栏体呈色对其下方落位带底色对比 ≥3:1〉。刷新入口已实装=营地刷新单口(进档与营地内写口尾触发,现开界面与顶栏余额同步取现值)。
## 叠层与开合
+2
View File
@@ -159,6 +159,8 @@ tests/
| 营地大门两分支确认与断点续玩接线 | 营地交互流 | 大门命中区 → 合成鼠标事件经 `push_input` 真点(`ProbeUiUtil.push_click_at`)→ ConfirmDialog 真钮(三出口)→ `main._on_confirm_accepted()`(新冒险确认)/`main._resume_from_menu()`(断点续玩) | `ui_click_probe.gd:_ready`(大门两分支段/断点确认段——真输入 push_click 驱动,2026-11-05 真输入化);`presentation_encapsulation_sweep_test.gd:_init`(迭代52卡③组合根交接面结构性主证——pres封装 V1–V4 四组私取零命中+新公开面正锚,2026-11-05 补链锚) |
| 四柜台拆解后五界面入口改挂与写口零回归 | 营地五界面 | 五界面意图信号 → `CampShopPresenter` → `MetaProgression.tree_buy()` 写口 | `forge_workbench_test.gd:_run`(承载类同迁断言十二项);`ui_click_probe.gd:_ready`(写口链段) |
| 营地篝火回主菜单与笔记本改挂动线 | 营地交互流 | 笔记本命中区真点(`push_click_at`)→ `CareerOverlay.open()`;篝火命中区真点 → ConfirmDialog 真钮二次确认 → 主菜单(2026-11-06 真输入化) | `ui_struct_probe.gd:_ready`(career 段);`screen_flow_probe.gd:_ready`(篝火/开合段——真输入驱动) |
| 确认弹窗按钮位次与语义同钉 | HUD框架 | `ConfirmDialog.open()`/`ConfirmDialog.open_three()` 开态读按钮行子节点序(定值=推进钮在左/次推进居中/维持钮在右,四处共用件同一序);探针在弹窗开态取按钮行 child(0) 的全局矩形中心经 `ProbeUiUtil.push_click_at` 真点 | `confirm_dialog_test.gd:_test_two_button_row_order`;`confirm_dialog_test.gd:_test_three_button_row_order`;`ui_click_probe.gd:_ready`(大门无断点段推进钮坐标真点) |
| 营地顶栏栏体定值与落座 | 营地场景视图 | 真实工程 boot 后经装配链 `MainUiBuild`→`CampSceneView.set_hud_band()` 读 `ui.modals.camp.scene.hud_band`(定值=`CAMP_HEADER_BAND`×α0.80、48px 全宽浮层、徽章右位顶格);单元经 `camp_scene_layout_table.gd` 的 `hud_band_h` 出口读背景贴图落位带像素算对比 ≥3:1 | `system_test.gd:_smoke_camp_hud_band`;`camp_scene_layout_test.gd:_test_hud_band_contrast_over_bg` |
| 关卡画面视口跟随 | 关卡画面(选路枢纽) | 停点切换与兑付回图经真实屏流程;读面 `LevelMapViewport.viewport_center_canvas_pos()` | `level_map_viewport_probe.gd:_probe_follow_anchor`;`level_map_viewport_probe.gd:_probe_smooth_scroll_reduced_motion` |
| 关卡画面视口平移 | 关卡画面(选路枢纽) | 合成拖拽沿与滚轮沿经 `push_input`(`ProbeUiUtil.push_drag_at()`/`push_wheel_at()`) | `level_map_viewport_probe.gd:_probe_drag_pan`;`level_map_viewport_probe.gd:_probe_wheel_pan`;`level_map_viewport_probe.gd:_probe_clamp_bounds_and_columns`;`level_map_viewport_probe.gd:_probe_drag_no_submit` |
| 关卡画面视口指引 | 关卡画面(选路枢纽) | 深图经 `LevelMapScreen.open_choices()` 真实停点 | `level_map_viewport_probe.gd:_probe_guidance_chrome` |
@@ -0,0 +1,109 @@
# 复核报告 · 营地交互修复批需求卡片(2026-11-05)
> 被复核对象:`reports/需求卡片-营地交互修复批-2026-11-05.md`(v1.0 成文态)
> 复核者:未参与撰写的只读子代理(独立会话,禁写文件、禁跑闸、禁运行游戏测试),任务=对卡内每一处行号、契约、判据逐条开火
> 复核轮次:1(第 16 节逐条登记去向与处置;本报告留发现原文与依据索引)
> 复核对象工作副本:`D:/code/g-plan2-camp-interact`(分支 camp-interact-20261105)
## 复核者总判原文(摘录)
> 按现状不能进实现段。缺四块闭合:①契约1 收窄措辞(否则实现首帧即自触 L3);②R3/R4 的按钮行句柄定义+§12 受控例外改判(否则判据落不了码);③T3.1 的 `UiAssembler` 引用形态+T3.2 内缩实现与 R5 的 x 向判据(否则 12px 无机制、断言可假绿);④R6 呈色输入来源改绑视图实件(否则撞 §8.7 第 5 条判红)。另有 6 处纯事实订正可自判直改。T 卡估时合计 0.25+0.5+0.75+0.5=2.0 与「≈1.75–2.0」自洽;四处消费方与 HUD框架:90 语义映射核过无冲突。
## 发现与依据索引(22 条)
| # | 卡内位置 | 发现 | 复核者给的依据 | 去向 | 写卡段处置 |
|---|---|---|---|---|---|
| 1 | §4 契约1 | 「隐藏点只许两处」按字面过宽,仓库另有 5 处以上 | `camp_shop_presenter.gd:43`、`main_overlay_flow.gd:8/41/95`、`main_debug_flow.gd:88` | 退回上游(复核者判) | 改自判:契约1 收窄为「限开局/续玩路径」,12 处显隐点逐条列名。定名不采纳——卡内措辞问题,非规范冲突 |
| 2 | §3.1 | `_start_adventure()` 行号段错(写 311) | `main.gd:308`=`return`,`:311`=下一函数声明 | 自判 | 改 292-308 |
| 3 | §9 T1.1 | 失败分支的开始层终态变化未申报 | `main.gd:306-307` `fatal_screen` | 补写 | §3.1 补终态申报 |
| 4 | §8 R2/§9 T1.4 | 段内 await 1 帧不足以让选路停点成形 | `ui_click_probe.gd:703`;先例 `screen_flow_probe.gd:186-192` 用 `_frames(3)` | 补写 | T1.4 补帧口径+实测最小帧数入实现报告 |
| 5 | §8 R3 | `btn_row` 是局部变量,判据无法写 | `confirm_dialog.gd:27`(成员仅 `:13-16`) | 补写(阻塞) | T2.1 升成员 `_btn_row`;R3 按 test-conventions §8.2 受控例外申报 |
| 6 | §12 | 自称不直取私有,实际 R3/R4 直取 | `confirm_dialog.gd` 成员表;`main._confirm_consumer` | 自判 | 改为受控例外口径,不再谎称 |
| 7 | §9 T2.3 | `:702` 真点已消耗 `gate_new`,R4 无左位可点 | 段结构 `ui_click_probe.gd:684-705`;`main.gd:215` 置空 | 补写 | T2.3 补前置重开步与坐标取法 |
| 8 | §10 L1 | `:679` 引用定性错;直发面在 `:697`;归属应系 §8.3 而非契约7 | 复核者回读 | 自判 | **部分不采信**:`:679` 经写卡段回读确为段头注「大门两分支断言段」,断点注入起 `:706`;直发行号实为 `:696`(复核者写 697 亦偏);§8.3 归属采纳。附带自查纠正 R8 的次钮断言行 `:696`→`:694` |
| 9 | §9 T3.1/§12 | `UiAssembler` 无 `class_name`,`views/` 零引用先例,卡内调用写法不成立 | `ui_assembler.gd:1-5`(`extends RefCounted`+头注「供组合根接线」)、引用方 `main_ui_build.gd:7`/`scenes/adventure_screen.gd:21`/`scenes/menu_screen.gd:15`、`views/` 内联先例 `battle_end_overlay.gd:261/289/314` | 待裁 | 第 15 节 Q1 两案并列;T3.1 改「待 Q1 后落」 |
| 10 | §3.3/§8 R5 | 徽章自高 48 系推导,`panel_flat` `border_w=1` 若计入则 50 | `ui_kit.gd:640`+`panel_flat` `ui_kit.gd:455-464`(复核者自标「这是推测,未跑批」) | 补写 | T3.0 新增前置读数;≠48 走 L3 第 5 条 |
| 11 | §9 T3.2/§11.3 | 12px 内缩无可达机制(宽度随位数变);R5 缺 x 向判据=改了仍绿 | `camp_hud_band.gd:16`(现值写死 x)+`:22`(文案「钥石 %d」) | 待裁+补写 | Q2 三案并列;R5 已补 `end.x == 栏 end.x − 12` |
| 12 | §8 R6 | 呈色若取自实现表达式=oracle 镜像 | test-conventions §8.7 第 5 条 | 自判 | R6 改规格侧写死值,禁喂视图件 color |
| 13 | §11.4 | 「4×8 步长沿该件口径」错,该件全像素扫描 | `terrain_tile_sets_test.gd:105-107` | 自判 | 白名单第 4 条改全扫描并声明旧口径作废 |
| 14 | 数学校核 | 全扫与抽样均色皆 RGB(223,235,232)(卡 `#DEEAE7` 差 ≤1/255);叠后 4.29:1、徽章对天空 1.30:1;落位带 0–48 只含背景成立 | `camp_scene_layout.tres:9`(背景 `Rect2(0,0,1280,800)`)、围墙 y=261、大门 y=250;`project.godot:30` 视口宽 1280 | 自判(确认+读数微差) | 差值落 L2 容差,阈值不放宽;卡内读数保留 |
| 15 | §1/§5 | 「七行」与对照表实数 R1–R8 不符 | 卡内自相 | 自判 | 改八行 |
| 16 | §5 | 引「第 1 节行为表」——卡内无该表(悬空引用) | 卡内自相 | 自判 | 改自足表述 |
| 17 | §7 | 结构图验收行缺 R7/R8 | 卡内自相 | 补写 | 两行补齐 |
| 18 | §13/§10 L3 第4条 | gdstyle 不扫 tests,新件三查与互斥条对新件无触发路径;套件入口是 `_initialize()` 非 `_init` | `tools/gdstyle_gate.py:45`(SCAN_DIRS 三目录)+头注 `:8`(probe/sim/tests 排除);`camp_scene_layout_test.gd:12` | 自判 | §13 改「对本件不适用」;L3 第 4 条限定 presentation 面;T2.2 入口名与先例行号订正 |
| 19 | §13 存量一查 | 核过无误:基线 `:11`=32、`:12`=23;`main.gd` 公开方法 31+1 静态=32 持平 | `tools/gdstyle_baseline.txt` | 自判(确认类) | 无改动,留档已核 |
| 20 | §4 契约4 依据 | 称五 token 对齐机检「查无该件」(`palette_check.py` 无 CAMP_HEADER 逻辑,全仓只命中视图用法) | 复核者 grep | 退回上游(复核者判) | **不采信其结论**:写卡段回读 `tools/palette_check.py:22` 有 `ui_tokens.png`=ui_kit 全量 Color8 token 快照基线,机制存在但不逐名比对表内五行;契约4 依据改成该准确口径 |
| 21 | §9 T2.2 | 册为硬编码清单,「接进套件册」不够具体 | `game/tests/run_all.gd:166` 起条目形态 `{"path":…, "expect":0}`+行尾注 | 补写 | T2.2 写死条目全文 |
| 22 | 横面 | `ANCHOR_RE` 字符类不含中文段→中文名现行文档无法被机检认锚 | `tools/pipeline_gate.py:68` | 退回上游 | 列 §6 末行;本批不动闸件,是否登记归用户发令 |
## 采信统计与残余
- 采信并落卡:19 条(自判 11/补写 8)。
- 转待裁(不代用户选):2 条(#9、#11 的机制案),落第 15 节 Q1/Q2。
- 不采信结论:2 条(#8 的 `:679` 定性、#20 的「机检不存在」),均经写卡段逐行回读推翻,依据记在表内。
- 残余(本卡范围外):#22 机检件缺口;以及本批既有的「art-bible §4.5 #7 破坏性确认异位是否追认」——早于本卡在册,见第 5 节不做表。
**卡片状态**:轮次 1 后为「待裁未清零」;轮次 2 后见下节。
---
## 轮次 2(Q1/Q2 裁决落卡之后,另起一个未参与撰写的只读子代理)
任务书限定只查五处,且每处须给 `文件:行号` 依据。发现五条:
| # | 卡内位置 | 发现 | 依据 | 去向 | 处置 |
|---|---|---|---|---|---|
| 1 | §8 R3/§9 T2.2 | 双钮形态断言「child(1)=维持」必红——次钮只 `visible=false`、不移除 | `confirm_dialog.gd:47` | 补写 | 改 child(2) + 子节点数=3 非空前置(已落卡) |
| 2 | §8 R5 | 未写「须先开营地」前置,boot 态营地屏为隐读不到尺寸 | `camp_scene_view.gd:51` | 补写 | 真实入口补 `open_camp()`+await 排版帧(已落卡) |
| 3 | §9 T3.0 | PanelContainer 最小尺寸入树排版后才可信,刚 `new()` 读数不可信,时机未写 | `ui_kit.gd:634-656` | 补写 | 改为经公开句柄读在树的现成实例、await 后再读(已落卡) |
| 4 | §3/§8 确认类 | 八处行号全对;`to_html(true)` 追加 α 两位、`6e4526cc` 串对;1280×48 尺寸链可达;「按类型找第一个 HBoxContainer」在本弹窗树内唯一 | `main.gd:211-212`/`:223-224`/`:292-308`、`ui_kit.gd:640`、`ui_assembler.gd:100/214/224-230`、`ui_kit.gd:189/190/200`、`standee_present_values_test.gd:36`、`scenes/camp_screen.tscn:7-11`、`project.godot:30-31` | 自判(留档) | 无改动 |
| 5 | §15 Q1 | 裁决句字面只覆盖「色值放公共层」这条轴,「矩形谁建」是写卡段的展开 | 对话原话序列:写卡段推荐句为「色值进公共件、矩形留在顶栏件自建」,用户回话「那没有问题,就按放在公共区域的这一层的方案来实现」 | 待裁(复核者判)→ 按自判落并报备 | 卡内第 15 节与第 16 节各写入解释面一句;用户不认该读法即重开,重开范围仅止于矩形建造方 |
轮次 2 总判:三条补写已落卡,一条确认留档,一条按自判落并向用户报备。**该"自判闭合"事后被判无效**——见轮次 3 与卡片第 15/16 节的裁决史。
---
## 轮次 3(11-06 用户驳回"值与形拆两处"、改判整案收编之后;第三个只读子代理)
| # | 卡内位置 | 发现 | 依据 | 去向 | 处置 |
|---|---|---|---|---|---|
| 1 | 契约4/§12 | 两处旧实现确未设 mouse_filter,ColorRect 默认即 STOP,出口默认值取 STOP 才不改三处旧遮罩语义 | `ui_assembler.gd:224-230`、`ui_kit.gd:486-491`;旁证 `ui_kit.gd:540`/`:864`、`camp_scene_view.gd:145` | 自判(确认) | 卡内补入旁证 |
| 2 | T3.2 | 三处既有调用点都是"挂宿主+把返回句柄当父用",转调在层序上等值 | `ui_assembler.gd:100-110`/`:214`/`:232-239`、`ui_kit.gd:511-514` | 自判(确认) | 无需改 |
| 3 | R9/T3.7 | `_modal_dim()` 经 `modal_shell()` 扇出 11 家消费件,R9 只点两处探针=覆盖不足 | `grep modal_shell(` 全仓 12 命中(含定义) | 补写 | 判据改源扫描式,并如实写明覆盖面(2 家断言+其余渲染闸与目检承接) |
| 4 | R5②⑤ | 1280 宽的承重链引错(非 tscn 锚点,是注册层 FULL_RECT);⑤ 全局矩形与局部 position 混写 | `camp_scene_view.gd:13-14`、`ui_registry.gd:26`/`:61` | 补写 | R5 改引注册层、⑤ 改 `get_global_rect()` |
| 5 | R9/T3.2 | "两文件 ColorRect 合计=1"算术不成立(`ui_kit` 实有 3 处自建) | `ui_kit.gd:487`/`:537`/`:862` | 补写 | 判据改为"两个被收编函数体内不再自建",范围显式声明,不写全仓唯一 |
| 6 | R9 | `:537` 页壳底板与出口形状相同、仅显式 STOP 与实色之差——是否同一件事,判为待裁 | `ui_kit.gd:536-542` | **待裁** | 新增 Q4(两案代价并列,不自决) |
| 7 | 多处 | 数字与交叉引用过期:显隐点 12→13(漏 `main_overlay_flow.gd:101`)、`views/` 自建先例 8 文件→7 文件 15 处、§5 与 §1 行数不一致、§12 步骤号未随重排更新、T4.1 应引 T3.9、§14/§15 把 tooltip 底误算进收编用途(`TIP_BG:190` 不经这两个函数) | `grep start_overlay.visible` 实测 13 处写点;`grep -c ColorRect.new()` views/*.gd 实测 7 文件 15 处 | 补写 | 全部按实测改正 |
| 8 | 轮次 2 记录 | 复核者上一轮给的 `camp_scene_view.gd:53` 才是正确行号,**写卡段上一轮"纠正复核者"改成的 `:51` 是错的** | 本轮 grep 复核 | 自判(推翻写卡段自己) | 全文改回 `:53`,卡片第 16 节轮次 3 记一条 |
**写卡段对轮次 3 的不采信项**:无——这一轮唯一被推翻的是写卡段自己上一轮的判断。
**轮次 3 总判**:不能进实现段;除 Q4 待用户一句裁决外,其余补写已全部落卡。
## 轮次 4(11-06 撤收编版落卡后的独立复核)
复核者=第四个未参与撰写的只读子代理(禁写禁跑,须给 `文件:行号`)。审的是撤收编后的终态(`UiKit.camp_hud_band_surface(host)` 单参具名出口+零收编)。它报 17 条:硬伤 2、事实错 2、一致性 4、补写 3、确认 5、外部 1;未新增待裁点。
| # | 卡片位置 | 发现 | 依据 | 去向 | 落卡 |
|---|---|---|---|---|---|
| 1 | R4 | 「按按钮行实际矩形算左位坐标」必打空:行 `alignment=CENTER`,双钮可见宽 216+12+216=444<壳宽 460,左位落 8px 空档 | `confirm_dialog.gd:29`、`ui_kit.gd:578`、`confirm_dialog.gd:20` | 补写 | R4 入口改取按钮行 child(0) 全局矩形中心并写入算式(与 T2.3 统一) |
| 2 | T3.4/§7/§11.5 | 「`_smoke_camp_hud_band()` 接进 `_initialize()`」不成立:`_initialize` 只调 `_split_tail()`,摘要与 `quit()` 在尾段,不被 await=静默不执行=假绿 | `system_test.gd:26-28`/`:35-48`/`:40` 行尾注/`:213-217` | 补写 | 三处同批改「接进 `_split_tail()` 的 await 链」,段内自持 instantiate/queue_free 照 `_smoke_run_lifecycle()` |
| 3 | §3.2/R3 | 四消费方行号偏一(卡 72/76-78/82,实 73/79-80/83;129 对) | `main_overlay_flow.gd:69-83`/`:125-129` | 自判 | 两处改正 |
| 4 | R5② | 营地场景根代码 new 的位置引错:`camp_scene_view.gd:13-14` 是命中区名表,new 在屏壳 | `camp_scene_view.gd:12-15`、`scenes/camp_screen.gd:13-14`、`camp_screen.tscn` 根锚 preset=15 | 自判 | 改引 `scenes/camp_screen.gd:13-14`(**同时推翻轮次 3 第 4 行沿用的 `camp_scene_view.gd:13-14`**) |
| 5 | R3 | 括注「`modal_shell()` 产 VBox+HSeparator」不实,HSeparator 是弹窗自加 | `ui_kit.gd:509-525`、`confirm_dialog.gd:26` | 自判 | 改为「产 CenterContainer+PanelContainer+VBox,不产横排」 |
| 6 | T3.3/§12 | 「`confirm_dialog.gd:27-29` 是容器右对齐先例」不准:该处 alignment 取 CENTER,是同机制先例 | `confirm_dialog.gd:29` | 自判 | 措辞改正,明写本件取 END 才是右对齐 |
| 7 | R6 | 「§8.4」未冠文档名,卡内无 8.4 小节 | `test-conventions.md` 正面效力自检条 | 自判 | 改「test-conventions §8.4」 |
| 8 | R4 | 读 `main._confirm_consumer`(私有)与 §12「不读私有」口径不一,但探针先例在案、扫描射程不含探针 | `ui_click_probe.gd:272`/`:286`、`presentation_encapsulation_sweep_test.gd:80-94`(该件在 `game/tests/unit/presentation/`,复核者误记 `unit/contracts/`) | 自判 | 主证改列 `is_adventure`,私有一读注明先例与射程;**路径误记已纠正,结论不受影响** |
| 9 | §14.1 | 出口职责句「返回句柄供顶栏件摆放徽章」与实际(返回值不用于摆位)不符 | 卡 T3.2/T3.3 | 自判 | 职责句改「供调用方读取与断言」,摆位归 T3.3 容器 |
| 10 | T3.0/L3.5 | 徽章自高≠48 只列描边一因,漏 18px 文字行高这一同因 | `ui_kit.gd:648`(Label 取 `FS_SUB`)/`:438` | 补写 | 两因并列,处置强度不变 |
| 11 | R2 | 判据非件1 改动特有面 | `ui_click_probe.gd:704` 既有同面断言 | 补写 | R2 注明特有提交面由 R1 承载、两行同批缺一即红 |
| 12 | 待办清单 | 实况仍写「两轮独立复核报告」 | `待办清单.md:30` | 补写 | 改「四轮」 |
| 13 | 全文 | 收编版残留扫描:无一处把收编/通用出口/color·pass_input/R9/改 `ui_assembler` 写成现行方案;T3.0–T3.7、R1–R8、白名单、L3、裁决史交叉引用零悬空 | 逐节比对+符号 grep | 确认 | 无需改 |
| 14 | 全文 | 40 处行号引用逐行打开无误(不含本表第 3、4 两条例外) | 复核者逐行比对 | 确认 | 无需改 |
| 15 | R5②③ | 未入树调 `set_anchors_preset(FULL_RECT)` 铺满成立、1280 宽承重链成立、色面必须入 `_init()`(入树前) | `ui_kit.gd:486-491`、`ui_assembler.gd:227`、`ui_registry.gd:61` | 确认 | 判据不变;按建议在 T3.4 补时机一句 |
| 16 | §2 实测句 | `Color(常量, α)` 构造子库内大量现役;const 引同文件 const 无库内先例,卡凭 11-06 临时工程实测(仓库无产物可复验=推测),失配属编译期 fail-fast | grep 零命中 | 确认 | 维持实测句,不设断言 |
| 17 | 契约/§5/§13/README | 契约4·5 与 §5 不做行无矛盾无空隙;两行新增能力名与 `tests/README.md:159/162/163` 逐字一致;预算实算正确(29 static func-6 私有=23→24) | 逐处比对 | 确认 | 无需改 |
**写卡段对轮次 4 的不采信项**:1 条——第 8 行的文件路径误记(实际在 `game/tests/unit/presentation/`),已按正确路径落卡,其结论经回读成立。
**轮次 4 总判**:两条硬伤与四处事实错、四条一致性问题、三条补写全部落卡,未新增待裁点。撤收编后的终态设计至此经独立复核闭合:零待裁点,开工门=U0(用户批卡)。
@@ -0,0 +1,438 @@
# 需求卡片 · 营地交互修复批(2026-11-05)
> **来源**:待办清单条目「营地交互修复批——大门无断点开局被开始层盖住/确认框钮序/营地顶栏无栏体」(2026-11-05 登记,来源=会话提及)
> **唯一事实源**:`design/gdd/ux/camp.md` v2.8 §顶栏 · §点选反馈 + `design/gdd/systems/表现与支撑/HUD框架.md` §提示与弹层(三条纪律·其三) + `design/gdd/systems/冒险循环/关卡节点地图.md` §核心循环位置 + `design/art/art-bible.md` v3.43 §6.2
> 验收档:中(三件做错的后果都是玩家可见但不损持久状态——呈现与交互逻辑;不触存档写读、不触结算公式、不触 RNG 流。判据=本技能第 16 节单维失败代价)
> **改动面**:游戏代码(`game/` 表现层+测试面)。文档面已由文档批落定为现行规格,本卡不携任何 `design/` 改动。
> **编排状态**:未编迭代(roadmap 现行最高编号=迭代 52,已完成;本卡待 iter-plan 段编排)
---
## 1. 目标与完成定义
三件互不相干的营地屏交互缺陷,一批修完:
1. **大门无断点开局被开始层盖住**——玩家点大门、按「是」之后,冒险其实已经开局,但主菜单层(开始层)重新显出来并把冒险画面盖住,玩家看到的是主菜单,误以为没开始。修完=从大门真实点击进入后,开始层不可见、关卡画面(节点图选路停点)可见。
2. **确认弹窗按钮位次反直觉**——同一个共用弹窗件把「维持现状」那颗放在左、「推进」那颗放在右,四处消费方(删档/大门三出口/大门两出口/篝火)皆然。修完=整体镜像为「推进在左、次推进居中、维持在右」,且位次与语义的绑定有真点验收。
3. **营地顶栏看不出是一行 HUD 栏**——顶栏件已装配、已落座、预留位 48px 全宽都在,缺的是那层看得见的底:现在是透明 Control 只挂一枚徽章,而徽章的烛光黄底对背后天空均色只有 1.29:1。修完=按 camp.md v2.8 §顶栏 定值画出栏体(`CAMP_HEADER_BAND` × 不透明度 0.80),徽章顶格右位落进栏内,并有尺寸与对比的机检。
**完成定义**:四条全落即算这批做完——
- 对照表(第 8 节)八行断言(R1–R8)在当轮真实跑批中执行且通过,无红项遗留;
- 第 8 节标注的两行新增能力已随写卡段落进 `game/tests/README.md`,实现批末核对名实相符;
- 回归面(第 5 节列的七条未改动动线)在跑批中仍绿,未因位次改动或栏体新增而失守;
- 末卡产出物(实现报告+反哺点清单)写齐,`reports/` 两份落位。
真人目检项(营地顶栏观感)登记进实现报告实机目检总清单即算义务了结,**不作合回前置**(AGENTS.md 红线:真人检测只登记不阻塞)。
---
## 2. 设计事实源
本节为卡片设计依据的唯一出处声明,与待办清单条目实况的闭合凭据同批一致:
| 需求点 | 现行规格句 | 出处 |
|---|---|---|
| 件1 | 点大门永远先出确认,无未完冒险=是否开始新冒险 | `design/gdd/ux/camp.md:16` |
| 件1 | 关卡开始 → 呈现节点图选路停点(关卡画面;入口不自动进入) | `design/gdd/systems/冒险循环/关卡节点地图.md:78` |
| 件2 | 确认弹窗的按钮位次定值:推进钮在左、维持现状钮在右,三钮形态次推进居中,四处共用同一件同一序 | `design/gdd/systems/表现与支撑/HUD框架.md:90` |
| 件3 | 栏体底=`#6E4526`×不透明度 0.80、高 48px 全宽浮层、栏内只钥石徽章一件右位顶格、验收=目检窄带可辨+机检对落位带底色 ≥3:1 | `design/gdd/ux/camp.md:41` |
| 件3 | 色板五件对齐表在册色 `CAMP_HEADER_BAND #6E4526`(机检〈ui_kit 五 token 与本表一致〉) | `design/art/art-bible.md:452` |
| 件3 | 命中区不侵入顶栏禁区(y ≤ 48) | `design/gdd/ux/camp.md:37` |
预览人审在案:2026-11-05 会话内实尺 HTML 预览(十张已过审场景层按 `camp_scene_layout.tres` 现值叠放+1:1 顶栏放大条+页内 WCAG 即时算式),用户审语「我看了预览的效果是OK的」,选定项=甲 深棕带 × 不透明度 0.80;快照文件 `chat-session-visualizations/…/visualizations/snapshot-444250310dc22234ac755b11fb31ce6885adb634b271c7083d53cc5d72b98640.html`(会话侧不可变快照,非仓库件)。像素级判据句已随附进 `camp.md` v2.8 §顶栏。
顶栏这块带子的落点定稿(用户 2026-11-05/11-06 四次裁决的终态,全程留痕见第 15 节 Q1 裁决史):**一个 UI 物件的外观不得拆两处**——色值与透明度、铺满方式、不吃点击、挂上宿主、返回句柄这五件事全在公共件 `ui_kit.gd` 的**一个具名公开出口**里;出口只接「挂到谁身上」一个形参,色与点击语义写死在它内部(它们是这块带子的定义,不是调用方每次要重述的选择)。同时**不收编盘上任何同形旧实现**:`ui_assembler.gd:224-230`、`ui_kit.gd:486-491`、`ui_kit.gd:537` 只是形状撞车、变化原因各不同,把它们绑进同一个出口=为没到来的问题做设计,并把回归面扩到全站弹窗底与两个全屏页。顶栏件只调该出口一次,不再自建 ColorRect。两项引擎实测(4.7.2,工程外临时工程跑通后即删,与本条封装方式无关,仍成立):①`Color(母token, 0.80)` 形态的 const 派生编译通过,`to_html(true)` 读数 `6e4526cc`、三分量与母 token 逐一相等;②**色道存单精度浮点,`.a == 0.80` 判为 false**(实测 `a=0.80000001192093`)——断言一律写 `to_html(true) == "6e4526cc"` 或整体等值比较,禁浮点分量直等,否则实现正确而断言红,最容易的自救就成了放宽阈值(触 test-conventions §8.5 禁止削弱测试)。
---
## 3. 现状事实(2026-11-05 实查;开工日自行复核行号)
### 3.1 件1——开始层可见性无单点
- `game/presentation/camp_shop_presenter.gd:85`:`on_camp_closed()` 体内无条件 `start_overlay.visible = true`。该函数的本职是「回主菜单」,篝火离场(`game/presentation/main.gd:214`)与 Esc 返回主菜单(`game/presentation/main_esc_flow.gd:46`)都靠这句显出菜单——**语义正确,不是缺陷本体**。
- `game/presentation/main.gd:211-212`(`_on_confirm_accepted()` 的 `"gate_new"` 分支)与 `game/presentation/main.gd:223-224`(`_on_confirm_secondary()` 的 `"gate"` 分支):两处都是先调 `camp_pres().on_camp_closed()`(把开始层显出来),紧接着调 `_start_adventure()`。
- `game/presentation/main.gd:292-308`:`_start_adventure()` 全函数体(体止于 `:308` 的 `return`,`:311` 已是下一函数声明行)零处触碰 `start_overlay`——于是上面那句「显出来」没有对手句把它收回去。失败分支(`main.gd:306-307` `fatal_screen`)在 T1.1 落笔后开始层终态由「可见」变「隐藏」,该终态差在本卡第 5 节明示为可接受(致命屏自会接管,无菜单可用)。
- 既有先例=每条启动路径在自己函数内部自管开始层:`game/presentation/main.gd:194`(`_start_adventure_from_menu()` 内先隐藏再转调)、`game/presentation/main.gd:246`(`_resume_from_menu()` 内隐藏)。所以现状的隐藏点是散在入口层的两处,缺的是开局那一条。
- `_start_adventure()` 全库调用点仅三处(`main.gd:195`/`212`/`224`),无一需要开局后保留开始层。
- 层序事实:`game/tests/system_test.gd:87-89` 断言「start_overlay 在冒险屏壳之上(盖住战斗内容)」——被盖住的正是冒险画面,故真机观感=「画面回主菜单」。
- 覆盖缺口事实:`game/presentation/main.gd:210` 的 `"gate_new"` 与 `main.gd:223` 的次确认分支,现有断言只核 `run_scope.is_adventure` 与营地场景屏隐藏(`game/probe/ui_click_probe.gd:703-705`),**没有一条核开始层可见性**,故缺陷在绿批里静默存活。
### 3.2 件2——弹窗件位次写死
- `game/presentation/views/confirm_dialog.gd:31-39`:`_init()` 内三颗钮的 `btn_row.add_child()` 次序=取消 → 次 → 确认。
- 信号按按钮对象路由、不按位次:`confirm_dialog.gd:32/35/38` 各自 `.pressed.connect(_emit_cancelled/_emit_secondary/_emit_confirmed)`——换序不改路由,文案也不用来认钮。
- 四处消费方(全部经同一件):删档确认 `game/presentation/main_overlay_flow.gd:129`(钮标「删除」/「取消」)、大门有断点三出口 `main_overlay_flow.gd:79-80`(「继续上一段冒险」/「开始新冒险」/「取消」)、大门无断点 `main_overlay_flow.gd:83`(「是」/「否」)、篝火离场 `main_overlay_flow.gd:73`(「离开」/「留下」)。
- 现有断言只核「次钮在两出口形态下隐藏」(`ui_click_probe.gd:696`),**无一条核位次**。
### 3.3 件3——顶栏件有装配无栏体
- `game/presentation/views/camp_hud_band.gd:10-17`:`_init()` 设 `PRESET_TOP_WIDE` + `custom_minimum_size=(0,48)` + `mouse_filter=MOUSE_FILTER_IGNORE`,体内只挂一枚徽章,**无任何底色件**——即整条顶栏是透明的。
- 徽章现状:`camp_hud_band.gd:15-16` 设 `PRESET_CENTER_RIGHT` 后 `position=Vector2(-160, 8)`(注释自标「代拍板 3」)。
- 徽章自高=48px:`game/presentation/views/ui_kit.gd:640` 的 `panel_flat(..., Vector4(14, 8, 14, 8))` 给图标 32px 上下各加 8px 内边距=48px,正等于栏高——**顶距 8px 在栏内放不下**,落座只能顶格。
- 装配链在位:`game/presentation/main_ui_build.gd:120-121` 造件并调 `set_hud_band()` → `game/presentation/views/camp_scene_view.gd:88-91` 把件塞进 `_hud_slot` → `camp_scene_view.gd:188` 预留位 `custom_minimum_size=(0, layout.hud_band_h)`,取数自 `game/data/tables/camp_scene_layout.tres` 的 `hud_band_h=48`(schema 见 `game/data/schemas/camp_scene_layout_table.gd:7`)。
- 盘上「新建 ColorRect+铺满宿主」的写法现有三处,意图各不相同,本批一处都不动:`game/presentation/ui_assembler.gd:224-230` `overlay_bg(host, color)`(亮底面板与模态压暗遮罩共用,外部调用者零、仅该文件自身 `:100`/`:214` 用,**没设 mouse_filter**);`game/presentation/views/ui_kit.gd:486-491` 私有 `_modal_dim()`(同一份东西的第二实现,同样不设 mouse_filter,仅 `:511` 经 `modal_shell()` 一处用、经该壳扇出 11 家模态消费件);`ui_kit.gd:537` 页壳底板(`page_shell()` 内,**显式**写 `MOUSE_FILTER_STOP`、色取 `BG_BRIGHT`/`BG_ROOT` 实色,其后紧跟石纹层与暗角层作兄弟节点)。三者与顶栏带只有形状撞车:前两者的变化原因是「遮罩挡不挡点击」,页壳底板的变化原因是「这块屏用哪档底色」,顶栏带的变化原因是「这条 HUD 带的定值」。另:顶栏件 `camp_hud_band.gd:14` 现役已在调 `UiKit.keystone_badge()`——视图件引公共件在本文件内就有先例,故出口落 `ui_kit`、不经装配器。用户 2026-11-06 终裁=**顶栏带的外观整件封进公共件一个具名出口,同形旧实现不收编**(早先两版——「值进公共件+矩形视图自建」与「四份同形收成带形参的通用出口」——都已作废,逐次理由见第 15 节 Q1 裁决史与第 12 节末段)。
- 落位带实际背景:营地背景层 `game/assets/art/scene/scene_camp_bg.png` 的 y0–48 带均色实测 `#DEEAE7`(逐像素取样,画面最上的可点物件是大门,顶缘 y=250,故 48px 带整条落在远景天空上)。徽章烛光黄底 `#F6C667` 对该天空 1.29:1;定值 `#6E4526`×0.80 叠后呈色 `#84664D`,对天空 4.27:1、对徽章底 3.31:1。
- 像素取样先例:`game/tests/unit/presentation/terrain_tile_sets_test.gd:107` 已用 `img.get_pixel()` 在单元套内取样贴图。
- 无 golden 锚:`game/tests/golden/README.md`「未建锚面备案」明写营地屏无改前 golden 锚,该面等价证据=探针/单元断言+实机目检。
---
## 4. 设计契约(红线,违反=L3 停机呈报)
- 🔴 **契约1|冒险启动路径的隐藏点收一处**:**限「开局」与「续玩」两条路径**——隐藏责任只许落在 `_start_adventure()`(开局)与 `_resume_from_menu()`(续玩)两个函数内部。第 3.1 条的先例形态即本契约依据。**本契约不管其余开层自管点**:全库开始层显隐共 13 处(`camp_shop_presenter.gd:43`/`:85`、`main.gd:137`/`:194`/`:246`、`main_adventure_flow.gd:145`、`main_debug_flow.gd:88`、`main_overlay_flow.gd:8`/`:17`/`:41`/`:48`/`:95`/`:101`),那些是选档层/生涯页/终局回菜单等各自开合面的自管句,本批一律不动、也不受本契约约束。禁再新增**开局或续玩路径**上的第三处隐藏点,禁把隐藏写回 gate 出口(调用方)。
- 🔴 **契约2|`on_camp_closed()` 语义不动**:`camp_shop_presenter.gd:85` 那句显示开始层是本批禁改项——篝火离场与 Esc 返回主菜单两条动线靠它。改动=回退主菜单功能。
- 🔴 **契约3|位次改动只动 `add_child` 次序**:`confirm_dialog.gd:31-39` 的三句连接(`.pressed.connect(...)`)、三个钮对象的创建与文案参数一律不动;四处消费方的 `open()`/`open_three()` 传参零改动。位次与语义的绑定由第 8 节 R4 行的坐标真点断言钉。
- 🔴 **契约4|这块带子的全部外观封在公共件的同一个具名出口里**:`ui_kit.gd` 出一个公开出口(本卡定名 `camp_hud_band_surface(host)`,实现可按同文件命名习惯微调后缀形态,见白名单第 6 条),**色值与 α、铺满、不吃点击、挂上宿主、返回句柄**五件事全在它内部;**形参只有 host 一个**——禁把颜色与「吃不吃点击」开成形参(那等于把这块带子的定义推回调用方每次重述,也正是本契约要禁的拆两处)。色值取派生常量 `Color(CAMP_HEADER_BAND, 0.80)`(三分量继承在册 token,同文件先例 `TOAST_BG:189`/`TIP_BG:190`/`HP_BAR_TRACK:200` 注「收口单点——非色板新增」)。**同时禁收编无关同形件**:`ui_assembler.gd:224-230`、`ui_kit.gd:486-491`、`ui_kit.gd:537` 三处原样不动,出口也不得被它们转调——形状撞车不等于同一件事,绑起来就得到一个同时要回答「页底用哪档色」「遮罩挡不挡点击」「HUD 带穿不穿点击」三个变化原因的函数,并把回归面扩到全站弹窗底(用户 2026-11-06 终裁,见第 15 节 Q1 裁决史④与第 12 节末段)。依据=`ui_kit.gd:2`「全站取色/描边唯一出口,换皮只改本文件」+ code-conventions §1.1 一个类一个职责、单一变化原因判据。色板快照不受新常量影响(`tools/gen_palette_baseline.py:42` 只正则 `Color8(数字,数字,数字)`,带 α 的 `Color(...)` 从不进快照)。
- 🔴 **契约5|不吃点击由出口内部保证**:栏体必须 `mouse_filter = Control.MOUSE_FILTER_IGNORE`,写死在出口内、不靠调用方记得设(顶栏件自身 `camp_hud_band.gd:13` 同款设置是既有锚)。漏设=48px 带内点击被栏体吃掉,与 `camp.md:37` 禁区纪律叠加成「顶排物件点不动」;且 ColorRect 默认即 STOP,漏设不会报错只会静默失守(同文件 `:540` 显式 STOP、`:864` 与 `camp_scene_view.gd:145` 须显式 IGNORE 为旁证)。本条与契约4 合起来把这块带子的外观压到一处。
- 🔴 **契约6|本批禁写文档面**:`design/` 整个目录、`待办清单.md`/`体验验证清单.md` 两份根流程清单、`game/tests/README.md` 一律禁改(能力两行已由写卡段落表,实现批只改名实相符);产出物只准落 `reports/`。
- 🔴 **契约7|禁变异类测试与撤销类取证**(test-conventions §8.4,全项目红线):本批所有断言从真实入口进入、绑被测改动特有的可观测提交面,禁人为制造红、禁回退 hunk 取证。
---
## 5. 范围边界
**做**:
1. `_start_adventure()` 入口收一个隐藏点,摘掉 `main.gd:194` 的冗余句;
2. `ConfirmDialog` 三颗钮的 `add_child` 次序整体镜像;
3. 公共件出一个具名出口封装这块带子的全部外观(色值与 α、铺满、不吃点击、挂上宿主、返回句柄)+ `CampHudBand` 改调该出口、徽章落座改右对齐容器;
4. 上述三件各自的测试(对照表 8 行 R1–R8)+能力清单两行(写卡段已落)+回归面确认。
**不做(含去向)**:
| 不做的东西 | 为什么 | 去向 |
|---|---|---|
| 「破坏性确认与常规确认禁止同位」(art-bible §4.5 清单 #7 后半句/interaction-patterns §7)在弹窗层的闭合 | 该句系 2026-09-14 文档骨架初版提交随件进入,全库查无用户裁决记录,且 battle.md:335 指定的无障碍基线权威(HUD框架 §可访问性基线)不含它——它是不是用户定的规则,本身待裁 | 本卡不动它;现状四处同位属既有状态,不随本批产生或消失。要不要闭合,归用户另发令,另立待办条目 |
| 顶栏栏内加第二件(存档位号/关卡语境等) | 用户 2026-11-05 裁「栏内只放钥石徽章一件」,左位不放件 | 无 |
| 营地场景层坐标、素材、七物件摆放的重排 | 属场景重排批,不与本卡混装(用户 2026-11-05 口径:代码批与素材批分两张卡) | 归那一批自己的卡 |
| 把盘上三处同形铺面写法(`ui_assembler.gd:224-230`、`ui_kit.gd:486-491`、`ui_kit.gd:537`)收敛成一个通用铺面器 | 形状同而变化原因不同(遮罩遮挡语义/页面底色档位/HUD 带定值);收编=把三个不相关变化原因绑进一个带形参的函数,回归面扩到全站弹窗底与两个全屏页底板,而这三个地方今天都没有待改的东西——为没到来的问题做设计(用户 2026-11-06 终裁,第 15 节 Q1 裁决史④) | 无。三处原样留底;日后若真出现意图相同的第二个消费者,届时按 code-conventions §1.1 重议 |
| 营地屏 golden 建锚 | 无改前基线可留底,新建锚不属缺陷修 | 不登记(顶栏观感走目检) |
| `main.gd:137` 的 boot 期 `start_overlay.visible = true` | 启动默认态,与三件无关 | 无 |
**回归面(本批不改、但跑批必须仍绿)**:七条未改动动线——大门有断点按「继续上一段冒险」/大门按「取消」「否」/篝火「离开」「留下」/Esc 浮窗三项/五功能窗开合/进入存档与生涯页返回的开始层显隐/终局回菜单。其中前三条已被 `ui_click_probe.gd:679-723` 段覆盖(段止于「开场行三路径段」头注之前),本批在该段内追加断言,不新建平行段。
---
## 6. 关联文档同步面
实现批禁写 `design/` 与根规则文件;下表逐条给出「要改哪一节、改成什么、依据是什么」,实现批把命中项列进 `reports/iter<53>-反哺点-<日期>.md`,由用户在会话中裁决后归文档批落文。
| 文档 | 关联点 | 同步义务 |
|---|---|---|
| `design/gdd/ux/camp.md` v2.8 §顶栏 | 本批把「栏体定值」变成实装;若实现期样张/目检意见要求改 α、改右位内缩或改栏高,现行句即落后 | 反哺点:只在**实际改值**时列,附实测读数;未改值不列 |
| `design/art/art-bible.md` v3.43 §6.2 钥石余额行 | 同上(该行已把事实源指回 camp §顶栏,改值须两处同改) | 反哺点:与上一行同批列,禁单改一处 |
| `design/gdd/systems/表现与支撑/HUD框架.md` §提示与弹层·其三 | 「四处共用同一件同一序」实装后须与代码一致;若实现发现某消费方不遵此序(例如自拼按钮行的弹窗件),句与码冲突 | 反哺点:发现即列,附 `文件:行` |
| `design/engineering/architecture/architecture.md` 呈现层模块表 | 两处随本批失真:`:175` CampHudBand 行现写「顶栏 48px 全宽窄条:**钥石余额 badge 唯一呈现**」——加可见栏体后badge 不再是唯一呈现物;`:168` D1 HUD 行的视图单元接口若因本批改动而与「信号外发、setter 只读注入」不符亦须同步 | 反哺点:实现批禁写该文档;本批落地后把该行的实际形态(栏体色面+badge 右位)列进反哺点清单,附 `文件:行` 与实装读数 |
| `体验验证清单.md` | 顶栏观感属「需真人试玩才能下结论」项,需一行观测项 | 反哺点:实现批禁写该清单,由文档批落;卡内先在实现报告目检总清单登记 |
| `game/tests/README.md` 能力表 | 两行新增能力已由写卡段落表(第 8 节能力行列名即清单名) | 实现批禁写;批末只核「清单名=实际落地函数名」,名实不符=停卡退回写卡段 |
| `roadmap.md` 迭代总表 | 本卡尚未编入迭代 | 非实现批义务,归 iter-plan 段 |
| (非文档面·写卡期发现一)`tools/pipeline_gate.py:68` 判据出处行锚的机检式 `ANCHOR_RE` 字符类=`[A-Za-z0-9_-.\\/]`,不含中文段 | 本库现行设计文档多为中文名(`HUD框架.md`/`关卡节点地图.md`/`待办清单.md`),凡判据句落在这类文档即无法被机检认锚——本卡 R2/R3/R4/R8 因此同时挂一个 ASCII 路径锚(`camp.md`/`level-map.md`),中文出处改以「第 N 行」散文形写明 | **已登记**:待办清单「流水线闸认锚式不含中文名文档」条(工具代码/待执行),本批不动闸件 |
| (非文档面·写卡期发现二)`game/tests/unit/contracts/source_guard_test.gd:85-99` 列目录不递归 | 「V1d 层序落位单口」的扫描面漏掉 `views/` 与 `scenes/` 两个子目录(注释仍写「presentation 无子目录」,实为两个);视图层的插位不在该闸视野内。当前无漏网真违规(`views/ui_kit.gd:841` 属卡片内部重排) | **已登记**:待办清单「层序落位单口检查的扫描面不含子目录」条(工具代码/待执行);两目录是否纳入扫描面本条不预裁,启动时再裁 |
---
## 7. 文件结构图
| 文件 | 职责 | 新增/改动 | 行为改动 | 验收行 |
|---|---|---|---|---|
| `game/presentation/main.gd` | 组合根:冒险启动与确认分派编排 | 改动(`_start_adventure()` 加一句;`_start_adventure_from_menu()` 删一句) | 行为改动 | R1、R2 |
| `game/presentation/views/confirm_dialog.gd` | 通用确认弹窗视图件 | 改动(三句 `add_child` 次序,**不动成员面**) | 行为改动 | R3、R4 |
| `game/presentation/views/ui_kit.gd` | 呈现层共享工厂与全站取色单点 | 改动(新增带 α 派生常量 + **新增一个具名公开出口**,该出口承载这块带子的全部外观;既有三处同形铺面写法一律不动) | 行为改动(顶栏呈现源) | R5、R6 |
| `game/presentation/views/camp_hud_band.gd` | 营地顶栏 HUD 件 | 改动(调该出口得栏体,不再自建 ColorRect;徽章落座改右对齐容器) | 行为改动 | R5、R6 |
| `game/probe/ui_click_probe.gd` | 真点探针:大门两分支段所在宿主 | 改动(同段追加断言) | 非行为改动(测试面) | R1、R2、R4、R7、R8 |
| `game/tests/system_test.gd` | 系统测试宿主 | 改动(新增 `_smoke_camp_hud_band()`,接进 `_split_tail()` 的 await 链〔`:40-44`〕) | 非行为改动(测试面) | R5、R8 |
| `game/tests/unit/presentation/camp_scene_layout_test.gd` | 营地屏布局与顶栏禁区单元套 | 改动(新增 `_test_hud_band_contrast_over_bg()`) | 非行为改动(测试面) | R6 |
| `game/tests/unit/presentation/confirm_dialog_test.gd` | 确认弹窗按钮位次与语义单元套 | **新增** | 非行为改动(测试面) | R3 |
| `game/tests/README.md` | 能力清单 | 改动(两行,写卡段落) | 非行为改动 | — |
结构图与第 12 节「落位与可复用性预检」互指:改动件七个(四件表现层+三件测试面)、新增件仅一枚单元套;这块带子的全部外观收在公共件的同一个具名出口里,出口只服务这块带子(判据见第 15 节 Q1 裁决史④与契约4)。
---
## 8. 验证闸(改动—验收对照表)
| 行 | 需求点(判据出处行锚) | 改动(文件:行/行为) | 验收测试(名称+落点+尾缀) | 层级 | 真实入口 | 判据绑定面 | 能力行 |
|---|---|---|---|---|---|---|---|
| R1 | 件1 大门无断点按「是」后开始层不可见(`design/gdd/ux/camp.md:16`+`design/gdd/systems/冒险循环/关卡节点地图.md:78`) | `main.gd:211-212` 分支经 `main.gd:292` 新入口隐藏 | `ui_click_probe.gd:_ready`(大门无断点段追加「确认后开始层不可见」) | 探针 | 营地场景根大门命中区 → `ProbeUiUtil.push_click_at` 真点 → 弹窗「是」钮 `ProbeUiUtil.push_click(_confirm_btn)` 真点 | `main.ui.screens.start_overlay.visible` 取值(被测改动特有的可见性提交面) | 既有:营地大门两分支确认与断点续玩接线 |
| R2 | 件1 开局落在节点图选路停点(`design/gdd/ux/level-map.md:69`;停点句唯一出处=`design/gdd/systems/冒险循环/关卡节点地图.md` 第 78 行「关卡开始 → 呈现节点图选路停点」) | 同 R1 | `ui_click_probe.gd:_ready`(同段追加「关卡画面在位」) | 探针 | 同 R1 真点链(大门命中区真点 →「是」钮真点) | `run_scope.is_adventure` + `main.ui.modals.run.level_screen.visible`(停点呈现面,非终态推断)。**本行是开局终态在位断言,被测改动的特有提交面由 R1 承载**——`is_adventure` 在既有探针已断(`ui_click_probe.gd:704`),把件1 的改动绑在它上不成立,故本行的效力=与 R1 同批缺一即红 | 既有:营地大门两分支确认与断点续玩接线 |
| R3 | 件2 两出口与三出口形态的按钮位次=推进→次→维持(`design/gdd/ux/camp.md:16`;位次定值唯一出处=`design/gdd/systems/表现与支撑/HUD框架.md` 第 90 行「三条纪律·其三」) | `confirm_dialog.gd:31-39` 三句 `add_child` 次序镜像;**成员面与连接一律不动** | `confirm_dialog_test.gd:_test_two_button_row_order`;`confirm_dialog_test.gd:_test_three_button_row_order` | 单元 | 视图件对外入口 `ConfirmDialog.open(text, confirm_label, cancel_label)`/`open_three(text, confirm_label, secondary_label, cancel_label)`——即四消费方实际用的那两个公开方法(`main_overlay_flow.gd:73`/`:79`/`:83`/`:129`) | 测试自己传入三档互异文案(如「推进」「次推」「维持」),从弹窗节点向下按类型定位那个横排容器(HBoxContainer),断言其 `get_children()` 的**子节点顺序**:双钮形态 child(0) 文案=「推进」且 **child(2)** 文案=「维持」——次钮在 `open()` 里只是 `visible=false`、不从子节点表移除(`confirm_dialog.gd:47`),双钮形态下子节点仍为 3 个,按下标断必须取 child(2)(写 child(1) 必红);三钮形态 child(0)/child(1)/child(2)=「推进」「次推」「维持」。另配非空前置:按钮行子节点数=3(防扫描面缩水静默绿)。按类型定位可成立已核:该弹窗树内只有这一个 `HBoxContainer`(`UiKit.modal_shell()` 产 CenterContainer+PanelContainer+VBox,不产横排——`ui_kit.gd:509-525`;`confirm_dialog.gd:26` 那条 HSeparator 与 `UiKit.button()` 的产件都不是 HBoxContainer)。判据面=树的公开子节点序(同 `system_test.gd:81-89` 断言层序的先例形态),**不读任何私有成员**,避开 `architecture.md:168` 视图单元接口与 `:323` 禁直引实现内部 | 新增:确认弹窗按钮位次与语义同钉 |
| R4 | 件2 左位那颗真点下去就是推进(`design/gdd/ux/camp.md:16`;位次定值出处同 R3) | 同 R3 | `ui_click_probe.gd:_ready`(大门无断点段内,`push_click_at` 打**推进钮自身**全局矩形中心) | 探针 | 弹窗开态下按类型定位按钮行 `HBoxContainer`,取其 child(0) 的 `get_global_rect()` 中心真点——**禁按「行矩形左位」算坐标**:该行 `alignment=CENTER`(`confirm_dialog.gd:29`),双钮可见宽 216+12+216=444<壳宽 460(`ui_kit.gd:578` 钮默认 `min_w=216.0`/`confirm_dialog.gd:20` 壳 `Vector2(460,0)`),左右各留 8px 空档,打行矩形左位会落空 | 主证=`run_scope.is_adventure` 翻转+`_confirm_consumer` 清零;真点前置读 `main._confirm_consumer == "gate_new"`(该私有的直读属**探针既有先例**,`ui_click_probe.gd:272`/`:286` 现役同款,封装扫描件只覆盖 flow 件的 `root._`——见 `presentation_encapsulation_sweep_test.gd:80-94`,故本行不新开辟读面)——位次若错接,坐标命中的将是「否」,主证面即红 | 新增:确认弹窗按钮位次与语义同钉 |
| R5 | 件3 顶栏栏体几何与徽章落座(`design/gdd/ux/camp.md:41`) | `camp_hud_band.gd:10-17` 改为调公共件出口得栏体+徽章落座改右对齐容器;`ui_kit.gd` 加带 α 常量与公开出口 | `system_test.gd:_smoke_camp_hud_band` | 集成 | 真实工程 boot 后经装配链 `main_ui_build.gd:120-121` → `camp_scene_view.gd:88-91` 落座;**须先开营地**(营地屏 boot 态为隐,`camp_scene_view.gd:53`),走 `main._camp_pres.open_camp()` 探针既有用法并 await 排版帧,再读 `main.ui.modals.camp.scene.hud_band`(`camp_scene_view.gd:49` 的公开句柄) | ①栏体色 `color.to_html(true) == "6e4526cc"`——即规格「`#6E4526` × α0.80」的字面编码;**禁写 `.a == 0.80`**(实测色道单精度使该比较为 false,见第 2 节实测句);②栏体铺满:出口产出的那块色面 `get_global_rect()` 宽=1280、高=48——**宽度不是 tscn 锚点给的**(营地场景根由屏壳代码 new——`game/presentation/scenes/camp_screen.gd:13` `CampSceneView.new()` + `:14` `add_child`,该根自身无锚无尺寸;承重实为 `ui_registry.gd:26`/`:61` 打的 FULL_RECT 注册,屏壳 `camp_screen.tscn` 根锚 preset=15 满铺),故实现首步先按 T3.0 同款时机量一次顶栏件现尺寸,再以此定断言值;③`mouse_filter == MOUSE_FILTER_IGNORE`;④栏体是顶栏件的**第一个子节点**(子节点序=绘制序,色面必须先入才不盖徽章);⑤徽章 `get_global_rect().position.y == 0` 且 `get_global_rect().end.x == 顶栏 get_global_rect().end.x − 12`(x 向缺判据则位次改错仍绿,故与顶格同批配齐;两项都用全局矩形,不与局部 `position` 混写)。前置量测=T3.0 读 `get_combined_minimum_size().y` 须为 48(描边若计入得 50 → 触第 10 节 L3 第 5 条) | 新增:营地顶栏栏体定值与落座 |
| R6 | 件3 栏体对落位带底色对比 ≥3:1(`design/gdd/ux/camp.md:41`+`design/art/art-bible.md:452`) | 同 R5 | `camp_scene_layout_test.gd:_test_hud_band_contrast_over_bg` | 单元 | 单元从 `camp_scene_layout_table.gd` 的 `hud_band_h` 出口取带高,读现行背景贴图 `res://assets/art/scene/scene_camp_bg.png` 该带像素(`load(...)` 取纹理再 `get_image()`+`get_pixel`,先例=`terrain_tile_sets_test.gd:105-107` 的全像素扫描) | 规格侧算式核验(与 R5 分工:R5 核实装等值,本行核规格值本身达标)=测试内按 `camp.md:41` 写死 `#6E4526` 与 α0.80,与该带实测均色 alpha 合成后算 WCAG 对比,断言 ≥3.0;扫描面非空前置照 test-conventions §8.4(正面效力自检)配齐。**禁把视图件的 color 直接当预期值喂进算式**(那是 oracle 镜像,test-conventions §8.7 判红) | 新增:营地顶栏栏体定值与落座 |
| R7 | 回归·件1 未动的三条动线(`design/gdd/ux/camp.md:16`/`:22`) | 无改动(`main.gd:208`/`214`、`main_esc_flow.gd:46`) | `ui_click_probe.gd:_ready`(既有大门两分支段+篝火离场段现有断言,本批零改写) | 探针 | 既有真点链 | 既有绑定面原样:`is_adventure` 不翻转、营地场景根 `visible`、`_camp_data()["balance"]` 不变 | 既有:营地大门两分支确认与断点续玩接线 |
| R8 | 回归·件2 未触的路由与件数断言(`design/gdd/ux/camp.md:16`;位次与件数定值出处同 R3) | 无改动 | `ui_click_probe.gd:_ready`(次钮隐藏断言 `:694`)+ `system_test.gd:_smoke_boot_chain`(开始层三钮计数 `:195`) | 探针/集成 | 既有真点与 boot 链 | 既有绑定面:`_secondary_btn.visible` 为假(两出口形态)、开始层可见钮数 == 3 | 既有:营地大门两分支确认与断点续玩接线 |
闸口径:本批改动含 `game/` 下非 `.md` 的行为载体,合回后远端 CI 走代码域全档;开发期按改完即测铁规以 `tools/run_all_gates.sh --code` 为选档入口(域划分唯一出处在脚本内,卡内不列闸件名单)。里程碑步出口跑一次所选档全套;波内修复只做出红件的最小单元最窄确认;新增测试先行孤立验证再并入全套。
**测试削弱申报**:允许改动 0 条既有断言。`ui_click_probe.gd:694`(次钮隐藏)与 `system_test.gd:195`(三钮计数)必须原样通过;本批位次改动若使二者失守=契约3 被违,停卡呈报,禁改判据求绿。**唯一允许的判据形态约束**:涉及色值与透明度的断言一律走 `to_html(true)` 或整体等值比较,禁浮点分量直等(第 2 节实测依据)。
**独立验收审计**:入口=`reports/iter<53>-验收审计-<日期>.md`;由未参与实现的只读会话或子代理执行,未过不得合回(test-conventions §8.7+iter 技能第 5 步)。验收档=中 ⇒ 审计深度按 §8.7 中档梯度。
---
## 9. 任务卡
### T1|开局路径的隐藏点收一处(≈0.25 工作日)
取用:`main.gd:292 func _start_adventure() -> void`(既有签名,零参数零返回)。
- [ ] T1.1 实装:`game/presentation/main.gd:292` `_start_adventure()` 函数体首行加 `ui.screens.start_overlay.visible = false`(位置在该函数现有第一句 `ui.flow.close(...)` 之前)。
- [ ] T1.2 实装:删除 `game/presentation/main.gd:194` 那句 `ui.screens.start_overlay.visible = false`(转调 T1.1 后它已无职责)。
- [ ] T1.3 验证:`python tools/run_system_test.py` 全绿——核 `_smoke_boot_chain` 与 `_smoke_run_lifecycle` 的既有开始层断言(`system_test.gd:170-171`/`:253`/`:261`)未失守。
- [ ] T1.4 验收:`ui_click_probe.gd` 大门无断点段(`:684-705` 区间内)追加两条断言并实跑——R1(确认后 `main.ui.screens.start_overlay.visible` 为假)、R2(`main.ui.modals.run.level_screen.visible` 为真,与既有 `is_adventure` 断言同批)。**帧口径**:段内既有 await 只 1 帧(`:703-704`),选路停点成形的先例是 3 帧(`screen_flow_probe.gd:185-193`,该段在 `await _frames(3)` 后断言「入口停点未落在关卡地图屏(level_screen 不可见)」——但它走 `_start_adventure_from_menu()` 函数直调,那条路径自带隐藏,所以从未抓到本缺陷)——追加断言前 await 到 3 帧,并把「停点成形所需最小帧数」实测值记进实现报告。落点=既有段内,不新建段。
- [ ] T1.5 验证:`python tools/run_all_gates.sh --quick` 对该件做最窄确认(探针闸段),先红后绿记进实现报告。
产出(T2/T3 无关,供回归引用):`_start_adventure()` 成为开始层隐藏的唯一开局出口。
### T2|确认弹窗按钮位次镜像(≈0.5 工作日)
取用:`confirm_dialog.gd:43 func open(text: String, confirm_label: String, cancel_label: String = "取消") -> void`;`confirm_dialog.gd:55 func open_three(text: String, confirm_label: String, secondary_label: String, cancel_label: String) -> void`。三颗钮的成员声明(`:14-16`)与连接属本卡禁动面,不取用。
- [ ] T2.1 实装:`game/presentation/views/confirm_dialog.gd:31-39` 三颗钮的 `add_child()` 次序整体镜像为 确认 → 次 → 取消。对象创建、`.pressed.connect(...)` 三句连接、成员声明(`:14-16`)、`open()`/`open_three()` 签名与文案参数一律不动(契约3)——**本卡不给测试开任何新成员或新公开出口**,位次判据走公开子节点序(依 `architecture.md:168` 视图单元接口与 `:323` 禁直引呈现层实现内部)。
- [ ] T2.2 验收(新增件):新建 `game/tests/unit/presentation/confirm_dialog_test.gd`,套件入口=`func _initialize() -> void`(视图件套形态先例=`camp_scene_layout_test.gd:12-13` 的 `call_deferred` 串法,**不是** `_init`),体内 `call_deferred` 两个私有函数——`_test_two_button_row_order()`:自造实例后调 `open("t", "推进", "维持")`,从该实例向下按类型定位那个 `HBoxContainer`,断言其 `get_children()` 的 child(0).text 为「推进」、**child(2).text** 为「维持」,且子节点数=3(次钮只置 `visible=false` 不移除——`confirm_dialog.gd:47`,双钮形态下维持钮在 child(2) 不是 child(1));`_test_three_button_row_order()`:调 `open_three("t", "推进", "次推", "维持")`,断言 child(0)/child(1)/child(2) 文案依次=「推进」「次推」「维持」。全程只读公开树面与 Button 的公开 `text`,不触任何私有成员。入册=在 `game/tests/run_all.gd:166` 起的硬编码清单里追加一行 `{"path": "res://tests/unit/presentation/confirm_dialog_test.gd", "expect": 0}` 并行尾注一句本套件职责(清单条目形态照同目录既有行)。
- [ ] T2.3 验收:`ui_click_probe.gd` 大门无断点段内追加 R4。**前置重开**:`:702` 那一次真点已把 `gate_new` 消费掉(`main.gd:215` 置空),故本步须先 `main._camp_pres.open_camp()` → `ProbeUiUtil.push_click_at(gate 命中区中心)` 重出弹窗,再取按钮行左位——坐标=自弹窗节点向下按类型定位到的 `HBoxContainer` 的 child(0) 全局矩形中心,经 `ProbeUiUtil.push_click_at` 真点;断言真点前 `_confirm_consumer == "gate_new"`、真点后 `run_scope.is_adventure` 为真且 `_confirm_consumer` 清零。
- [ ] T2.4 验证:孤立先跑 T2.2 新套(`… --script res://tests/run_all.gd` 单套件口径),绿后并入全套;四处消费方动线由 `ui_click_probe.gd` 既有段与 `run_all` 单元套确认未失守(R8)。
产出:位次成为规格钉死的呈现定值,推进钮恒为该按钮行的 child(0)。
### T3|营地顶栏可见栏体(整件外观封在公共件一个具名出口,≈0.75 工作日)
取用:`UiKit.CAMP_HEADER_BAND`(`ui_kit.gd:195`,色值单点);`UiKit.keystone_badge(text: String) -> KeystoneBadge`(`ui_kit.gd:655`);`CampHudBand._init()`(`camp_hud_band.gd:10`,该件 `:14` 现役已在调 `UiKit`)。**盘上三处同形铺面写法不在取用面**(`ui_assembler.gd:224-230`、`ui_kit.gd:486-491`、`ui_kit.gd:537`)——本批既不让顶栏件复用它们,也不把它们收编进出口,理由见第 3.3 条、契约4 与第 12 节末段。
- [ ] T3.0 前置读数:**入树之后**再量——`KeystoneBadge` 是 PanelContainer(`ui_kit.gd:634-656`),最小尺寸由容器排版产出,刚 `new()` 未入树时读数不可信。落点=在系统测试宿主里经 `main.ui.modals.camp.scene.hud_band` 链取**已在树的现成徽章实例**,先开营地并 `await` 排版帧(帧数口径同 T1.4),再读 `get_combined_minimum_size().y`(`ui_kit.gd:640` 的 `panel_flat(...Vector4(14,8,14,8))` 加在 32px 图标上下各 8=48,两个未证实项都能把它推离 48:①`border_w=1` 是否计入最小尺寸;②徽章内 Label 用 18px 档(`ui_kit.gd:648` 取 `FS_SUB`,常量见 `:438`),字体行高若大于 32 则最小高由文字而非图标决定——**这两条都是推导,不是实测量**)。读数=48 → 按 T3.3 顶格落座;读数≠48(如 50)→ 停步走第 10 节 L3 第 5 条呈报,禁自行改栏高或改徽章内边距。读数与取数时机一并写进实现报告。
- [ ] T3.1 实装·出口本体(Q1 终裁·11-06 用户裁「整件外观封在公共件一个具名出口,同形旧实现不收编」):`game/presentation/views/ui_kit.gd` 色板段加 `const CAMP_HUD_BAND := Color(CAMP_HEADER_BAND, 0.80)`(带 α 先例=同文件 `:189`/`:190`,收口非新增语义色的先例=`:200`);工厂段加公开出口 **`static func camp_hud_band_surface(host: Control) -> ColorRect`**,体内依次=新建 ColorRect + `rect.color = CAMP_HUD_BAND` + `rect.set_anchors_preset(Control.PRESET_FULL_RECT)` + `rect.mouse_filter = Control.MOUSE_FILTER_IGNORE` + `host.add_child(rect)` + `return rect`。**形参只有 host**:色、α、铺法、点击语义全写死在体内——这就是「一个物件的外观不得拆两处」的确切实现形(对照两个作废形态:值在公共件+铺法在视图=拆两处;出口开 color/pass_input 形参=把物件定义推回调用方,并为无关同形件预留通用性)。出口名钉死在这块带子上,不作通用铺面器。
- [ ] T3.2 实装·顶栏件:`camp_hud_band.gd` 的 `_init()` 内在挂徽章之前调 `UiKit.camp_hud_band_surface(self)`(契约5 的 IGNORE 由出口内部保证,调用方没有可以忘记的形参);子节点序即绘制序,栏体先入、徽章后入。本文件内不再出现 `ColorRect.new()`。
- [ ] T3.3 实装·徽章落座(**Q2 已裁乙·2026-11-05 用户裁**):`camp_hud_band.gd` 内加一层右对齐容器承载徽章——`HBoxContainer` 铺满栏体(`PRESET_FULL_RECT` 后置 `offset_right = -12.0`)、`alignment = BoxContainer.ALIGNMENT_END`、**`mouse_filter = Control.MOUSE_FILTER_IGNORE`(容器自身默认 STOP,与出口内那处 IGNORE 是两个点、必须同批落,漏一处顶排物件就点不动)**;替换 `camp_hud_band.gd:15-16` 现值(`PRESET_CENTER_RIGHT` + `position=(-160, 8)`),位数增宽自然向左展。容器摆位机制先例=`confirm_dialog.gd:27-29`(同件同机制,那里 alignment 取 CENTER、这里取 END);内缩 12px 见白名单第 3 条。
- [ ] T3.4 验收:`game/tests/system_test.gd` 新增 `_smoke_camp_hud_band()`,**接进 `_split_tail()` 的 await 链**(`:40-44` 那一串 `await _smoke_*()` 之后追加 `await _smoke_camp_hud_band()`),**不是接进 `_initialize()`**——`_initialize()` 只调一句 `_split_tail()`(`:26-28`),而摘要打印与 `quit()` 都在该尾段末尾(`:47-48`),协程段不被 await 就会在首个 await 处被 quit 截断=静默不执行=假绿(该教训已写在 `:40` 行尾注里)。段内自持 `load("res://presentation/main.tscn").instantiate()`+`root.add_child`+await 帧、末了 `queue_free()`,形态照 `_smoke_run_lifecycle()`(`:213-217`/`:206-207`)。实现 R5 的五项判据(色值走 `to_html(true) == "6e4526cc"` 或整体等值比较,**禁浮点分量直等**;`get_global_rect()` 的尺寸=顶栏件实测宽 × 48;`mouse_filter == MOUSE_FILTER_IGNORE`;栏体是顶栏件的第一个子节点;徽章全局矩形 `position.y == 0` 且 `end.x == 顶栏 end.x − 12`)。**出口须在 `_init()`(入树前)被调**:`set_anchors_preset(PRESET_FULL_RECT)` 是把四边 offset 归零的入树前动作,与 `_modal_dim()`/`overlay_bg()` 的现役形态一致。
- [ ] T3.5 验收:`game/tests/unit/presentation/camp_scene_layout_test.gd` 新增 `_test_hud_band_contrast_over_bg()` 实现 R6:读 `hud_band_h` 与背景贴图该带**全像素**均色(取样法照 `terrain_tile_sets_test.gd:105-107` 的双层全扫,非步长抽样),规格值 `#6E4526`/α0.80 按 `camp.md:41` 在测试内写死后合成算 WCAG 对比,断言 ≥3.0;扫描面非空前置照 §8.4 配齐。
- [ ] T3.6 验证:两条新测先行孤立跑绿再并入 `--code` 全套。本批不触任何既有遮罩/亮底/页壳件,故无等值回归义务——回归证据=第 5 节七条未改动动线与全站弹窗现有断言在 `--code` 全档中仍绿。营地屏截图面由渲染闸的七屏段随批产出,作 R5/R6 对照取证。
- [ ] T3.7 目检登记:营地顶栏观感(「成一条可辨窄带、徽章落在带内」)登记一行进实现报告实机目检总清单,登记即完成义务。
产出:`CAMP_HUD_BAND` + `camp_hud_band_surface()` 是这块带子外观的唯一出处(同文件相邻两段);`CampHudBand` 的外观=该出口+右对齐容器+徽章三件,视图内无一处自建 ColorRect;盘上三处同形写法原样未动。
### T4|产出物落位卡(≈0.5 工作日,末卡)
- [ ] T4.1 代码域全档全绿后、合并前写 `reports/iter<53>-实现报告-<日期>.md`:各卡状态+实机目检总清单(含 T3.7)+遗留读数义务+实现决定记录(超白名单的微决策逐条登记)。
- [ ] T4.2 写 `reports/iter<53>-反哺点-<日期>.md`:第 6 节每条命中项都要有落点(哪一节、改成什么、依据什么);无命中也要写「本批零反哺点」并附核过哪几处。
- [ ] T4.3 核对 `game/tests/README.md` 两行新增能力名与实际落地函数名逐字一致(名实不符=停卡退回写卡段)。
- [ ] T4.4 呈报合回清单,等用户发令再走收口(冻结→件核→并 master→重塑→删区)。
**估时合计 ≈2.0 个工作日**(T1 0.25+T2 0.5+T3 0.75+T4 0.5)。T3 的 0.75=出口一枚(十行内)+顶栏件改两处(调出口+落座容器)+两条新测+孤立验证。无收编、无等值回归、无两次全档义务。
---
## 10. 异常分级
- **L1 自救**:探针坐标算错导致 R4 打空——重算按钮行全局矩形中心,禁改为信号直发(段内既有 `ui_click_probe.gd:696` 的 `cancelled.emit()` 是取消路径的信号注入先例,注释自陈「真实信号——cancelled 钮同源」;本批 R4 要钉的正是**位次**,直发不经位次,等于没测——依据=test-conventions §8.3 真实入口收窄条,契约7 同源)。
- **L2 记录继续**:R6 均色取样读数与卡内实测 `#DEEAE7` 有 ≤3/255 的取样步长差——按实测值断言、卡内读数差写进实现报告,不改阈值。
- **L3 停机呈报(写报告等用户)**:
1. boot 后 `main.ui.modals.camp.scene.hud_band` 取不到实例(装配链与第 3.3 条现状不符)=卡片现状事实失效,停卡退写卡段;
2. R4 坐标真点无法区分左位钮与相邻钮(按钮行 `alignment=CENTER` 下实际矩形与规格不符)=位次与语义绑不上观测面,触 test-conventions §8.4「判据绑不上=停卡呈报」出口;
3. 位次改动使 `system_test.gd:195` 或 `ui_click_probe.gd:694`(次钮隐藏断言)失守=契约3 被违,禁改判据求绿;
4. 机检预算互斥限**本批触碰的 presentation 面文件**:`tools/gdstyle_gate.py:45` 的扫描面=`game/core`/`game/data`/`game/presentation`,脚本头注(`:8`)明写排除 probe/sim/tests——故新增单元套**不在** S13 射程,该条只对 `main.gd`/`confirm_dialog.gd`/`camp_hud_band.gd` 生效。若这三个件的 S13 键与第 13 节预算数字冲突且无豁免通道=上游缺陷,停卡退回写卡段,禁自造第三条路(本技能第 13/14 节)。
5. T3.0 量得徽章 `get_combined_minimum_size().y` ≠ 48(描边宽 1px 计入、或 18px 文字行高高于 32px 图标使最小高由文字决定,两条都会推得 >48)=「顶格落座」在 48px 栏内放不下,第 2 节与 `camp.md:41` 的推导句失效,停步呈报,禁自行改栏高、改徽章内边距或放宽 R5 判据。
---
## 11. 代拍板白名单(超清单必进实现报告「实现决定记录」并呈报)
1. 断言消息尾缀文案(照 `〔营地图批 V3〕` 形态自拟)。
2. 新单元套件的套件注册名与 `run_all.gd` 册内落点序。
3. **徽章水平内缩 12px**:`camp.md` v2.8 只钉「右位顶格」未钉内缩值,取 UiKit 钮间距同档 12(先例=`confirm_dialog.gd:28` `separation=12`)。
4. R6 取样密度——照 `terrain_tile_sets_test.gd:105-107` 的**双层全像素扫描**(该件不是步长抽样,卡内早先写的「每 4 行×每 8 列」口径作废)。
5. `_smoke_camp_hud_band()` 在 `_split_tail()` await 链内的插入位(不改变既有段序;接进 `_initialize()` 不成立——见 T3.4)。
6. 出口与常量的命名(卡内定名 `UiKit.camp_hud_band_surface()` 与 `CAMP_HUD_BAND`)——可按同文件命名习惯微调后缀形态;**若实现把它改成带 color/pass_input 形参的通用铺面器、改成「值与形分两处」、或另起第二家公共出口,一律触契约4,属 L3 呈报**。
不在白名单:α 值、栏底色、栏高、位次序、隐藏点数量与位置——这些是规格钉死项,改动一律 L3 呈报。
---
## 12. 落位与可复用性预检(与第 7 节结构图互指)
| 新增/改动件 | 复用面(盘上已有什么) | 唯一面 | 分层与交互面 |
|---|---|---|---|
| 顶栏带外观出口(T3.1/T3.2) | **现成件已复用**:徽章走 `UiKit.keystone_badge()`(`ui_kit.gd:655`,`camp_hud_band.gd:14` 是现役调用方),色值走在册 `CAMP_HEADER_BAND`(`:195`)。盘上另有三处「新建 ColorRect+铺满宿主」的同形写法(`ui_assembler.gd:224-230` 外部调用者零、`ui_kit.gd:486-491` 私有且仅 `:511` 一处用、`ui_kit.gd:537` 页壳底板)——**本批三者都不复用也不收编**:它们的变化原因是遮罩遮挡语义与页面底色档位,与本带的 HUD 定值无关。出口落 `ui_kit`、不经装配器,因顶栏件已在引用 `UiKit`,而 `views/` 引装配器零先例。早先两版判据(「两份都不复用、按 views 现行形态自建」与「四份同形收成带形参的通用出口」)都已作废,逐次理由见第 15 节 Q1 裁决史 | 这块带子的外观全仓一处定义=`CAMP_HUD_BAND`+`camp_hud_band_surface()`(同文件相邻两段);禁在别处出现第二组「同一色+同一 α」;出口内 `MOUSE_FILTER_IGNORE` 写死——旁证:同文件 `:540` 页壳底板显式写 STOP、`:864` 与 `camp_scene_view.gd:145` 须显式写 IGNORE,可见 ColorRect 默认即 STOP,漏设不报错只会静默吃掉顶排点击 | 呈现层内一个纯构建出口,零状态、零信号、不持引用;顶栏读数仍经 `camp_data()` 投影单口(`camp_hud_band.gd:26-27`);`ui_assembler.gd` 与 `modal_shell()`/`page_shell()` 一律不动 |
| 开始层隐藏(T1.1) | **复用** 既有语义句本身——`main.gd:194`/`:246` 就是同一条责任,本卡把它收进被调方 | 开局路径隐藏点唯一(`_start_adventure()`),续玩路径唯一(`_resume_from_menu()`);其余 10 处开层自管点不在本契约射程(契约1 已收窄) | 组合根内;不触 Core,不新增信号 |
| 按钮位次(T2.1) | 无新增件——只镜像既有三句的次序。**本卡不新增成员、不新增公开出口**:位次判据走公开子节点序(R3),语义判据走坐标真点(R4) | 位次定值只写在视图件 `_init()` 一处,四处消费方零副本 | 呈现层;信号对象路由不动;依 `architecture.md:168`「视图单元接口=信号外发+setter 只读注入」与 `:323`「禁直引呈现层实现内部」,不为测试开成员面(该写法曾在本卡出现过,已撤回,登记在第 16 节轮次 2) |
| 徽章落座(T3.3,Q2 已裁乙) | 已有做同样事的东西:`HBoxContainer` + `alignment` 摆位机制(`confirm_dialog.gd:27-29`——该件 `alignment` 取的是 `ALIGNMENT_CENTER`,**是同一机制的先例、不是右对齐的先例**;本件同处改取 `ALIGNMENT_END` 即右对齐)——**Q2 已裁乙(2026-11-05 用户裁)**,采容器右对齐形态;另两案(锚点生长、`size_updated` 回调)作淘汰留档见第 15 节 | 内缩值 12px 只在落座一处出现一次,禁在断言里另写第二套推导 | 呈现层内 |
| `confirm_dialog_test.gd`(T2.2 新增) | 盘上无 ConfirmDialog 专属单元套(grep 命中面=`system_test.gd`/探针的宿主级引用与 `README.md:159` 能力行);同目录 `camp_scene_layout_test.gd:12-13` 是可参照的套件形态(入口 `_initialize()`+`call_deferred`),不是可复用的承载 | 位次判据只此一处;R4 探针判据与之互补(一个核序、一个核语义) | 测试层;经 `ConfirmDialog.open()/open_three()` 公开入口进出,断言只读公开子节点序与 Button 的公开 `text`——「读私有成员」的写法曾在 R3 出现,已按 `architecture.md:323` 撤回 |
| `system_test.gd:_smoke_camp_hud_band`(T3.4)/`camp_scene_layout_test.gd:_test_hud_band_contrast_over_bg`(T3.5) | **扩展**既有套件,不新建宿主;取样法复用 `terrain_tile_sets_test.gd:105-107` 的双层全扫+`get_pixel` 路径 | 几何判据落系统测试、对比判据落布局单元套——两处职责已由套件名界定,禁第三处重复断言 | 测试层 |
**为什么出口只服务这块带子(2026-11-06 用户终裁;本段取代本卡此前两份互相矛盾的留痕句——「接受第四处重复故不抽工厂」与「四份同形收成带形参的通用出口」)**:用户裁的是两件事的合成。①**一个物件的外观不得拆两处**——色值、α、铺法、点击、挂载这五件事必须在同一个出口内定义,不许「常量在公共件、矩形在视图」;那等于要求每个改它的人同时记得两处,漏一处就得到一个自相矛盾的物件。本会话确有改漏实例:同一组色值要在两份文档里成对改,卡内同步面还写了「禁单改一处」的防呆,却在代码面上造出另一个新的成对结构。②**抽不抽公共器不由形状撞车决定**——不得为了「全仓只剩一处 ColorRect 铺满」这种读数好看,把遮罩、页底、HUD 带三个变化原因绑进一个带形参的通用器;那既不内聚(一个函数回答三个不相关的问题)也不低耦合(改顶栏带要回归全站弹窗底与两个全屏页),而这三处今天都没有待改的东西。**早先那份「三次法则、意图未第三次出现故不抽工厂」的留痕句,其动机经用户点破是「少动文件」而非纪律,作废**;但据此反弹出的「整案收编+形参化点击语义」同样作废。代价面(`ui_kit` 公开方法 23→24 须修订登记基线)见第 13 节例外申报;回归面因不收编而留在本件射程内,估时相应回落。
---
## 13. 实现规范预算(与第 7 节结构图互指)
**新件三查**——本批新增文件仅 `game/tests/unit/presentation/confirm_dialog_test.gd`:
- **三查对本件不适用**:`tools/gdstyle_gate.py:45` 扫描面=`game/core`/`game/data`/`game/presentation`,脚本头注 `:8` 明写「probe/sim/tests 测量面」排除——测试面文件不进 S13 读数,无键可对账。
- 尺寸预期(照套件形态先例自持,不作机检项):套件入口 1 个(`func _initialize() -> void`,**非** `_init`——先例=`camp_scene_layout_test.gd:12-13`)+私有 `_test_*` 2 个+类变量 0–1。
- 迁移函数对账:无迁入(该件全新增,`tools/gdstyle_baseline.txt` 无历史键,跑批后若出超默认新键须申报)
**存量触面一查**——S13 键较登记值只降不升:
| 文件 | 基线登记(`tools/gdstyle_baseline.txt`) | 本批预期 |
|---|---|---|
| `game/presentation/main.gd` | 第 11 行 `quality/max-public-methods = 32` | 不动公开方法面(函数体内加一句+另一函数删一句)→ 读数 32 持平 ✓ |
| `game/presentation/views/ui_kit.gd` | 第 12 行 `quality/max-public-methods = 23` | 本批**加一枚 `const` + 加一个公开出口方法** → 读数预期 23→**24**,超登记值 → 见下方「指标例外申报」。色板快照面不受常量影响(`tools/gen_palette_baseline.py:42` 只正则 `Color8(数字,数字,数字)`,带 α 的 `Color(...)` 从不进快照,同文件 `TOAST_BG`/`TIP_BG` 即此形态);但**方法数是真升**,不申报就是假绿 |
| `game/presentation/views/confirm_dialog.gd` | 无登记键(在默认阈值内) | 仅语句重排,分支与返回数不变 ✓ |
| `game/presentation/views/camp_hud_band.gd` | 无登记键 | `_init()` 换成调出口+加一层容器,分支数不变 ✓ |
| `game/probe/ui_click_probe.gd` | 无登记键(探针大文件另有基线口径) | 同段追加断言,函数不拆;若单函数分支数超默认,按 L3 第 4 条呈报而非自拆 |
| `game/tests/system_test.gd` | 无登记键 | 新增一个私有函数,公开方法面不变 ✓ |
**指标例外申报(本批一项)**:`game/presentation/views/ui_kit.gd|quality/max-public-methods` 由登记值 23 升至 24,起因=用户 2026-11-06 裁「一个物件的外观不得拆两处」,要求在公共件出一个公开出口承载这块带子的整件外观。处置=实现批跑出该新键后,把 `tools/gdstyle_baseline.txt` 该行改为 24 并在提交信息里申报(基线手动修订须经用户批准——本条即申报与请求)。除此之外本批不申请任何超默认项。
---
## 14. 拆分边界纪律
本批新增的可复用单元只有公共件里那一个出口函数,故本节条款的适用面=该出口,判据权威=code-conventions §1.1 拆分判据,此处不复制定文:
1. **它有可陈述的职责与单一变化原因**:`UiKit.camp_hud_band_surface()` 的职责语句=「把营地顶栏这块带子按定值铺满宿主并挂上去,返回句柄供调用方读取与断言」;单一变化原因=这块带子的外观要变(以后要求圆角、内缩、换遮挡方式,都只改这一个函数+那枚常量)。它不承载玩法状态、不承载文案、不做判定、不接形参选择;徽章的摆位不由它负责(归顶栏件内那层右对齐容器,T3.3)。
2. **集体身份成立**:它服务的是营地顶栏这一块具名带子,不是「所有 ColorRect 铺满动作」的收纳盒。**故意不做**成通用铺面器:若把模态遮罩、页壳底板一并收进来(用户 2026-11-06 否掉的形态),这个单元就从「一块带子的定义」变成「三种不相关意图的并集」——正是拆分判据要拦的形态。
3. **「过阈值」只作发现信号**:本批不以任何计数变好看为目标;公开方法数上升是它的代价(见第 13 节例外申报),不是它的动机。
4. **拆不出内聚单元即停卡呈报**:若实现期发现该出口必须塞进条件分支才能同时容纳顶栏带与其它用途,说明本卡对「只有这一个消费者」的判断失真——停卡呈报退设计段重议,禁硬并为凑绿。新增单元仅这一个出口函数+一枚常量+一个私有测试套件,无段件/状态件迁出。code-conventions §1.1 与本节互指;实现期若需拆 `camp_hud_band.gd` 或 `main.gd` 才落得下,属卡片未预见的结构动作=L3 呈报,禁为凑绿硬拆。
---
## 15. 待裁点(三轮复核产生;Q1 因写卡段自决被驳回而重开过、又因出口的执行形态被再裁一次——全程留痕)
独立复核(未参与撰写的只读子代理)三轮:轮次 1 打回一次,四条闭合里三条由写卡段按权威文档自决落卡,第四条拆成两案呈用户裁决;轮次 2 抓到「矩形谁建」这条轴属越权自决;轮次 3 抓到收编版四处硬伤并生成 Q4。**当前状态:Q1/Q2/Q3 已裁尽,Q4 因 11-06 用户再裁而消解(不再是一条分叉),本卡零待裁点,开工门=U0(用户批卡)。**
### Q1|顶栏这块色面从哪来——**已裁(终态=公共件一个具名单参出口,同形旧实现一律不动)**
事实底座:`ui_assembler.gd:224-230` 的 `overlay_bg()` 做了「新建 ColorRect+铺满锚点+挂上宿主+返回句柄」四步,**没设 mouse_filter**(ColorRect 默认 STOP),外部调用者零(只有该文件自身 `:100` 传 `BG_BRIGHT` 亮底、`:214` 传黑 0.6 遮罩);`ui_kit.gd:486-491` 的私有 `_modal_dim()` 是同一份东西的第二实现(同样不设 mouse_filter,仅 `:511` 一处用);`ui_kit.gd:537` 页壳底板同形但**显式**写 STOP、色为实色、后有石纹/暗角兄弟层;`views/` 目录自建 ColorRect 有 7 个文件 15 处先例;顶栏件 `camp_hud_band.gd:14` 现役已在调 `UiKit`。
当时并列过的案与代价:甲=顶栏件 preload 装配器复用那一个出口(零重复,但给 `views/` 开一条该目录零先例的引用路径,且该文件头注自陈「接线拓扑唯一归组合根」);乙=顶栏件自建(与 `views/` 现状同构,但重复四行,且色值与铺法分居两处);丙=公共件出一个出口(真「整件外观一处定义」,代价是 `ui_kit` 公开方法 23→24 要修订登记基线)。
> **裁决史(四次)**
> ① **11-05**:用户裁「就按放在公共区域的这一层的方案来实现」。写卡段把它解释成"采纳我当轮给的整条推荐",落成**色值进公共件+矩形留在视图自建**,并在第 12 节写下"不抽公共工厂"的留痕句。
> ② **11-06 用户驳回①并重裁**:驳回理由是那条解释本身——"值"和"形"是同一个 UI 物件的两半,拆两处就要求每个改它的人同时记得两处,而"少动文件"不是纪律。**当时落成的重裁结果=丙的整案**:公共件出一个 `band_surface(host, color, pass_input)` 通用出口封装铺面与点击语义,并把 `_modal_dim()`、`overlay_bg()` 连同三处调用点同批收编,据此生成 Q4。
> ③ **11-06 写卡段据 Q4 呈「页壳底板收不收」**,用户判该设计整体不成立(原话:「你现在是有非常严重的设计问题」)——出口一旦需要形参承载三种点击语义,它就不再是「一个物件」而是三个意图的并集;会问出 Q4 本身就说明抽象切错了。
> ④ **11-06 终裁(现行)**:出口**只服务营地顶栏这块带子**——具名 `camp_hud_band_surface(host)`,**形参只有 host**,色值、α、铺满、穿点击全写死在体内;`ui_assembler.gd:224-230`、`ui_kit.gd:486-491`、`ui_kit.gd:537`、`ui_kit.gd:862` 一律**不收编、不动**。已落契约4/5、§2、§3.3、§5、§7、§12、§14、T3.1–T3.3。
> ⑤ 流程账:轮次 2 复核当时已把①那条轴标为**待裁**(原话:裁决句字面只覆盖色值轴),写卡段改成"自判+报备"自行闭合——那是越权(规矩:待裁必须问用户、禁代裁),第 16 节轮次 2 相应行按实情登记。
### Q2|徽章「右位顶格+内缩 12px」用什么机制随位数自适应——**已裁(2026-11-05 用户裁乙·容器右对齐)**
事实底座:徽章文案是 `"钥石 %d" % v`(`camp_hud_band.gd:22`,格式串单点在 `UiKit` badge 工厂),**宽度随余额位数变**;现值 `position = Vector2(-160, 8)`(`camp_hud_band.gd:16`)把 x 写死——R5 要断言「徽章右缘 == 栏右缘 − 12」,写死偏移在位数变化时必然失位(现值 -160 只对当时那个位数读数成立)。
| 案 | 做法 | 代价 |
|---|---|---|
| 甲 | 锚点右钉 + `grow_horizontal = GROW_DIRECTION_BEGIN` + `offset_right = -12`、`offset_top = 0` | 纯声明式、无回调;依赖 Control 生长语义(须开工首步实测读数确认,Godot 4.7 锚点+offset 与 custom_minimum_size 的相互作用我不凭记忆断言) |
| 乙 | 栏体内套一个右对齐 `HBoxContainer`(`alignment = END`),徽章作子件由容器摆位 | 与 `UiKit` 既有容器用法同构(弹窗钮行 `confirm_dialog.gd:27-29` 就是 `HBoxContainer` + `alignment`);代价是多一层容器节点,栏体色面与容器的父子关系要重排 |
| 丙 | 保持现锚点,接徽章 `size_updated` 信号在回调里重算 x | 改动面最小;代价是多一条运行期回调路径(与「显式触发才变」的顶栏刷新纪律并存,需在卡内申报新观测路径) |
写卡推荐=**乙**,理由=仓内已有同类摆位先例(容器 `alignment` 摆位,非手算偏移),且 R5 的 x 向判据在容器形态下读数最直白。甲依赖我不肯凭记忆断言的引擎语义(AGENTS.md:不确定的 API 一律核实后再用,核实前不作推荐)、丙新增运行期路径。
> **裁决(2026-11-05 用户裁·乙 容器右对齐)**:已落 T3.3 与第 12 节,Q2 清零。
**Q1/Q2 与第三条(闸件缺口是否登记)都已裁完并落卡,本卡零待裁点,开工门=U0。**
### Q4|页壳底板要不要一并收进同一个出口——**已消解(11-06 用户终裁:不收编,出口只服务顶栏带)**
留档(非现行分叉):`ui_kit.gd:537` 页壳底板与出口形状相同(新建 ColorRect、赋色、铺满、挂上宿主),差别是它**显式**写 `MOUSE_FILTER_STOP`、色取 `BG_BRIGHT`/`BG_ROOT` 实色,且后面紧跟石纹层与暗角层作兄弟节点——它是「页面底」,不是「遮罩/条带」。`ui_kit.gd:862`(竖卡 18×16 小色块)不同形(手工 position/size、不铺满)。轮次 3 把前者判为待裁并生成 Q4,呈报时并列「不收编(甲)/一并收编(乙)」两案。用户回话否定的是这条呈报的**前提**:出口本来就不该是通用铺面器,所以「第四处收不收」不成立。按终裁④,`ui_assembler.gd:224-230`、`ui_kit.gd:486-491`、`ui_kit.gd:537`、`ui_kit.gd:862` 四处全部原样不动。
### 其余复核发现的处置(已落卡,非待裁)
自判与补写两类已按复核者自己落卡的规矩改进行内:契约1 收窄措辞、`_start_adventure()` 函数体行号订正、失败分支终态申报、帧口径、R6 输入来源改读实件、R8 行号与能力行拆正、结构图验收行补 R7/R8、悬空「行为表」引用、L1 引用行号、白名单第 4 条取样口径、`_initialize()` 入口名、新件三查对 tests 不适用、`main.gd:137` 与其余开层点不受契约1 约束的明示、R3 child(2) 硬伤、R5 开营地前置与 await 时机、T3.0 入树读数时机、1280 宽承重链改引 `ui_registry.gd:26`/`:61`、徽章 x 向判据改全局矩形、显隐点 12→13、`views/` 先例 8 文件→7 文件 15 处、步骤号与 R 行口径重编号。(轮次 1 对 R3 给的「升成员供测试直取」处置已在轮次 2 撤回——它抵触 `architecture.md:168` 视图单元接口与 `:323` 禁直引呈现层实现内部,改判为公开子节点序判据。)
两条闸件面发现**均已登记为工程改动待办**(用户 2026-11-05 口径:登记后本批不管):认锚式字符类不含中文段(`tools/pipeline_gate.py:68`)、层序落位单口的扫描面不含子目录(`game/tests/unit/contracts/source_guard_test.gd:85-99`)。两条都在待办清单在册(改动面=工具代码/状态=待执行),本批不动闸件。
复核未采信两条:复核者称 `ui_click_probe.gd:679` 是断点写盘句(实为段头注,断点注入在 `:706` 起);称 art-bible:452 宣称的五 token 机检「查无该件」(`tools/palette_check.py:22` 的 `ui_tokens.png` 就是 ui_kit 全量 Color8 token 快照基线,机制存在,只是不逐名比对该表五行——已写进契约4 依据,未采纳其结论)。
---
## 16. 复核记录
复核者身份=未参与本卡撰写的只读子代理(Agent 工具起的独立会话,禁写文件、禁跑闸),形态=只读子代理。轮次 1,发现 22 条,四类去向逐条登记:
| 轮次 | 复核者身份 | 发现(一句话) | 去向 | 处置结果 |
|---|---|---|---|---|
| 1 | 只读子代理·未参与撰写 | 契约1「隐藏点只许两处」按字面过宽——全库开始层显隐共 13 处 | 退回上游(复核者判)→ 落卡改自判 | 契约1 收窄为「限开局/续玩两条路径」,13 处逐条列名(`camp_shop_presenter.gd:43`/`:85`、`main.gd:137`/`:194`/`:246`、`main_adventure_flow.gd:145`、`main_debug_flow.gd:88`、`main_overlay_flow.gd:8`/`:17`/`:41`/`:48`/`:95`/`:101`)。复核者的「退回上游」定名不采纳:这是卡内条款措辞过宽,非规范冲突,写卡段可自改 |
| 1 | 同上 | `_start_adventure()` 函数体行号错(写 311,实止 308) | 自判 | §3.1 改 `292-308` 并注明 `:311` 是下一函数声明行 |
| 1 | 同上 | T1.1 落笔后启动失败分支的开始层终态由可见变隐藏,卡未申报 | 补写 | §3.1 该行补终态申报(致命屏自接管,无菜单可用) |
| 1 | 同上 | 大门段 await 只 1 帧,选路停点成形先例是 3 帧 | 补写 | T1.4 补帧口径+最小帧数实测记进实现报告;引 `screen_flow_probe.gd:185-193` |
| 1 | 同上 | `btn_row` 是 `_init()` 局部变量,R3「逐位相等」写不出来 | 补写(阻塞) | 当时把 `btn_row` 升为成员并申报受控例外;该处置在轮次 2 撤回(抵触 `architecture.md:168` 视图单元接口与 `:323` 禁直引呈现层实现内部),现行判据=公开子节点序,不新增成员 |
| 1 | 同上 | §12 自称「不直取私有」,R3/R4 实际直取私有成员 | 自判 | 同上:先改为受控例外口径,轮次 2 再改为完全不读私有成员(R3 走子节点序、R4 走坐标真点) |
| 1 | 同上 | `:702` 真点已消耗 `gate_new`,R4 需重开营地+大门才有左位可点 | 补写 | T2.3 补「前置重开」步与坐标取法 |
| 1 | 同上 | L1 引用的 `ui_click_probe.gd:679` 不是旧口径注释;段内直发面在 `:696`;「emit 不算真实入口」属 §8.3 而非契约7 | 自判+**部分不采信** | L1 改引 `:696` 的 `cancelled.emit()` 并注依据=test-conventions §8.3。**但复核者称 `:679` 是断点写盘句,经我回读不成立**——`:679` 确为段头注「大门两分支断言段」,断点注入起 `:706`;另 R8 原引 `:696` 亦错,次钮隐藏断言实为 `:694` |
| 1 | 同上 | `ui_assembler.gd` 无 `class_name`,现网一律 preload,`views/` 零先例;卡内 `UiAssembler.overlay_bg(...)` 写法不成立 | 待裁 | 第 15 节 Q1 全案并列(复用装配器/视图内自建/公共件出出口),含三案代价;T3.1 改为「待 Q1 裁决后落」 |
| 1 | 同上 | 徽章自高 48 系推导,`panel_flat` 带 `border_w=1`,描边若计入则 50、R5 顶格判据即红 | 补写(复核者自标「这是推测,未跑批」) | T3.0 新增前置读数步(量 `get_combined_minimum_size().y`);≠48 走 L3 第 5 条;§3.3 与 R5 的推导句标为未实测 |
| 1 | 同上 | 12px 内缩无可达机制(徽章宽随位数变,现值写死 x 偏移);R5 只断 y 向,x 写错仍绿 | 待裁+补写 | 第 15 节 Q2 三案并列(锚点生长/容器右对齐/size_updated 回调);T3.3 改「待 Q2 裁决后落」;R5 已补 x 向判据(`end.x == 栏 end.x − 12`) |
| 1 | 同上 | R6 若把实现的 `Color(UiKit.CAMP_HEADER_BAND, 0.80)` 当输入=oracle 镜像 | 自判 | R6 改为规格侧算式核验(测试内按 `camp.md:41` 写死 `#6E4526`/α0.80),并明写「禁把视图件 color 喂进算式」,依据=test-conventions §8.7 |
| 1 | 同上 | §11.4 称 4×8 步长「沿 `terrain_tile_sets_test` 口径」错,该件是全像素扫描 | 自判 | 白名单第 4 条改全像素双层扫描,并声明卡内早先步长口径作废 |
| 1 | 同上 | 数学校核:全扫与抽样均色=RGB(223,235,232),与卡内 `#DEEAE7` 差 ≤1/255;叠后对比 4.29:1(卡 4.27)、徽章对天空 1.30:1(卡 1.29) | 自判(读数采纳,容差不改) | 落位带前提经其独立核对(背景层 `Rect2(0,0,1280,800)`、围墙 y=261、大门 y=250 → 0–48 带只含背景);差值落 L2 容差内,不放宽阈值 |
| 1 | 同上 | §1 完成定义与 §5 写「七行」,对照表实为 R1–R8 | 自判 | 完成定义改「八行(R1–R8)」(收编版曾扩到 R9,随该版作废回到八行) |
| 1 | 同上 | §5 引「第 1 节行为表」,本卡无该表(悬空引用) | 自判 | 改为「七条未改动动线」自足表述 |
| 1 | 同上 | §7 结构图 `ui_click_probe`/`system_test` 的验收行列缺 R7/R8 | 补写 | 结构图两行补齐 R1、R2、R4、R7、R8 / R5、R8 |
| 1 | 同上 | gdstyle 只扫 core/data/presentation,tests 不在面 → §13 新件三查与 L3 第 4 条对新件无触发路径;套件入口是 `_initialize()` 非 `_init` | 自判 | §13 三查改「对本件不适用」并给依据(`tools/gdstyle_gate.py:45`+头注 `:8`);L3 第 4 条限定为 presentation 面三件;T2.2 入口名改 `_initialize()` 并附先例行号 |
| 1 | 同上 | §13 存量一查核过无误(基线 32/23,`main.gd` 公开方法 31+1 静态=32 持平成立) | 自判(确认类) | 无需改动,留档为已核项 |
| 1 | 同上 | 契约4 依据「加枚即触五 token 机检表」查无该件 | 自判+**不采信其结论** | 复核者称机检不存在,经我回读:`tools/palette_check.py:22` 的 `ui_tokens.png`=ui_kit 全量 Color8 token 快照基线,机制在——只是不逐名比对该表五行。契约4 依据改写成这个准确口径,仍禁新增 token |
| 1 | 同上 | `run_all.gd` 册是硬编码清单,T2.2「接进套件册」不够具体 | 补写 | T2.2 写死条目形态 `{"path": "res://tests/unit/presentation/confirm_dialog_test.gd", "expect": 0}` +行尾注,并指 `run_all.gd:166` 起的清单 |
| 1 | 同上 | 总判:按现状不能进实现段,缺四块闭合 | 退回上游(部分) | 四块里①②④已自决落卡;③的 `UiAssembler` 形态与 12px 机制转 Q1/Q2 待裁。另其归入的机检缺口(`pipeline_gate.py:68` `ANCHOR_RE` 不含中文段)已列 §6 末行,去向=用户发令登记 |
**写卡段对复核结论的两处不采信**(复核者也是读代码,不是跑批):`:679` 段头注的定性、五 token 机检「查无该件」——两处均经我逐行回读推翻,依据写在对应处置格。
**复核报告落盘**:`reports/复核-营地交互修复批-2026-11-05.md`(轮次 1=22 条,轮次 2=5 条,轮次 3=8 条,同一文件续段登记)。
## 轮次 2(Q1/Q2 首次裁决落卡后的独立复核)
复核者身份=第二个未参与撰写的只读子代理(与轮次 1 不同一会话),任务书限定只查五处并须给 `文件:行号` 依据。
| 轮次 | 复核者身份 | 发现(一句话) | 主去向 | 处置结果 |
|---|---|---|---|---|
| 2 | 只读子代理·未参与撰写 | **硬伤**:双钮形态下断言「child(1)=维持」必红——次钮在 `open()` 里只置 `visible=false`、不从子节点表移除 | 补写 | R3 与 T2.2 改判 child(2),并配「按钮行子节点数=3」非空前置;依据 `confirm_dialog.gd:47` |
| 2 | 同上 | R5 缺前置:营地屏 boot 态为隐,未开营地读不到尺寸 | 补写 | R5 真实入口补「先 `open_camp()` + await 排版帧」;依据 `camp_scene_view.gd:53` |
| 2 | 同上 | T3.0 未写取数时机:PanelContainer 的最小尺寸在入树排版后才可信,刚 `new()` 读数不可信 | 补写 | T3.0 改为「入树后经公开句柄读在树的现成徽章实例,await 排版帧再读」;依据 `ui_kit.gd:634-656` |
| 2 | 同上 | 确认类(无发现):八处行号全对(`main.gd:211-212`/`:223-224`/`:292-308`/`:194`/`:246`、`ui_kit.gd:640` 带 `border_w=1`、`ui_assembler.gd:100`/`:214`/`:224-230`、`ui_kit.gd:189/190/200`);`to_html(true)` 追加 α 两位、期望串 `6e4526cc` 对;尺寸链 1280×48 可达(CampScreen 满铺+`_hud_slot` 全宽,父链无容器改写);「按类型找第一个 HBoxContainer」不会找错(该树只有一个) | 自判(确认留档) | 无需改卡,核法记档:逐行打开比对+仓内既有用法 `standee_present_values_test.gd:36`(`to_html(false)` 六无 #) |
| 2 | 同上 | Q1 的裁决句「按放在公共区域的这一层」字面只覆盖色值落点;「矩形由顶栏件自建、不抽公共工厂」是写卡段对裁决的展开,该轴轮次 1 原属甲/乙案内容 | **待裁(复核者判,事后证明它判对)** | 写卡段当时把去向改成"自判+报备"并自行闭合——**该改判无效**:规矩是待裁必须问用户、禁代裁。11-06 用户驳回拆两半的方案,落点见第 15 节 Q1 裁决史②与④;本行处置因此从"已闭合"改记为"越权闭合→已由用户重裁" |
**轮次 2 总判**:三处补写已落卡(现行有效);一处确认留档;一处按自判落并向用户报备(该自判后被用户驳回)。
## 轮次 3(11-06 收编版落卡后的独立复核,第三个未参与撰写的只读子代理)
复核者身份=第三个只读子代理(与前两轮不同会话,禁写禁跑)。它抓到 6 项:4 项我照改、1 项它判对而我上一轮判断错、1 项转用户裁决。
| 轮次 | 复核者身份 | 发现(一句话) | 主去向 | 处置结果 |
|---|---|---|---|---|
| 3 | 第三只读子代理 | 两处旧实现确实没设 mouse_filter、ColorRect 默认即 STOP——出口默认值取 STOP 保旧语义的做法成立 | 自判(确认) | 该事实现行有效,已并入契约5 作「漏设不报错」的旁证(`:540` 显式 STOP、`:864`/`camp_scene_view.gd:145` 显式 IGNORE);「出口默认取 STOP」这一设计随收编版作废 |
| 3 | 同上 | 三处既有调用点都是"挂宿主+把返回句柄当父用",收编为转调在层序上等值 | 自判(确认) | 随收编版作废(11-06 终裁不收编),留档 |
| 3 | 同上 | `_modal_dim()` 经 `modal_shell()` 扇出 **11 家**模态消费件,R9 只点两处探针不足以覆盖 | 补写(收编版内部) | 随收编版作废;它揭示的事实(该私有件扇出面广)现作为**不收编的理由**并入契约4 与 §5「不做」表 |
| 3 | 同上 | **卡内 1280 宽的承重链引错**:宽度不是 tscn 锚点给的,是 `ui_registry.gd:26`/`:61` 的 FULL_RECT 注册撑出;R5 第⑤条还把全局矩形与局部 `position` 混写 | 补写(且推翻我自己) | **现行有效**:R5 改引注册面并把⑤改为 `get_global_rect()`。**同一条我上一轮"纠正"错过**:我曾判 `camp_scene_view.gd` 初始隐在 `:51` 并把复核者的 `:53` 改回去,本轮 grep 复核实为 `:53`,已全文改回 |
| 3 | 同上 | R9/T3.2 的收编完成判据算术不成立:`ui_kit.gd` 现有 3 处 ColorRect 自建(`:487`/`:537`/`:862`),"两文件合计=1"必红 | 补写(收编版内部) | 该判据随收编版作废;它抓到的事实(同形写法实为三处,不止两处)保留,现行 §3.3/§12 按三处陈述 |
| 3 | 同上 | `:537` 页壳底板与出口同形(铺满+纯色),仅显式 STOP 与色不同——形状同而语义是否同,判为待裁 | **待裁(转用户)** | 当时列进第 15 节 Q4;用户 11-06 回话否定该呈报的前提(出口不该是通用铺面器),Q4 消解,见 Q1 裁决史③④ |
| 3 | 同上 | 卡内多处数字与交叉引用过期:显隐点 12→**13**(漏 `main_overlay_flow.gd:101`)、`views/` 自建先例 8 文件→**7 文件 15 处**、§5 写 R1–R8 而 §1 写 R1–R9、§12 三处步骤号、T4.1 目检引用、§14 与 §15 把 tooltip 底算进收编用途(`TIP_BG:190` 是主题色常量,不经这两个函数) | 补写 | 数字类改正(13 处、7 文件 15 处)现行有效;tooltip 底不属于任何用途清单,现行 §3.3 按「亮底/黑 0.6 遮罩/页底/顶栏带」四种意图分述;步骤号与 R 行口径随本轮撤收编重编号一并落定 |
**写卡段对轮次 3 的不采信项**:无(它唯一被我推翻的是我自己上一轮写错的 `:53`,本轮已按它的正确值改回)。
**轮次 3 之后的改判**:轮次 3 审的是「收编版」;11-06 用户终裁(Q1 裁决史④)撤掉收编与带形参的通用出口,本卡据此重落成「一个具名单参出口」——该终态须经一轮新的独立复核才算闭合,遂有轮次 4。
## 轮次 4(11-06 撤收编版落卡后的独立复核,第四个未参与撰写的只读子代理)
复核者身份=第四个只读子代理(与前三轮不同会话,禁写禁跑,任务书要求逐条给 `文件:行号`)。它报 17 条:2 条硬伤、4 条事实错/一致性问题、2 条补写、5 条确认无发现;**未新增待裁点**(无需用户裁决)。发现与处置:
| 轮次 | 复核者身份 | 发现(一句话) | 主去向 | 处置结果 |
|---|---|---|---|---|
| 4 | 第四只读子代理 | **硬伤**:R4 字面「按按钮行实际矩形算左位坐标真点」必打空——该行 `alignment=CENTER`,双钮可见宽 216+12+216=444<壳宽 460,行矩形左位落在 8px 空档上 | 补写 | R4 真实入口改为取按钮行 child(0) 的 `get_global_rect()` 中心,并把算式与依据行号写进格内(`confirm_dialog.gd:29`、`ui_kit.gd:578` `min_w=216.0`、`confirm_dialog.gd:20` 壳宽 460)——**我回读三行确认成立**;T2.3 原本就写的就是 child(0) 中心,两处口径现已统一 |
| 4 | 同上 | **硬伤**:T3.4 让 `_smoke_camp_hud_band()` 「接进 `_initialize()`」不成立——`_initialize()` 只调 `_split_tail()`,摘要与 `quit()` 都在尾段,不被 await 的协程段=静默不执行=R5 假绿 | 补写 | T3.4/§7 结构图/§11 第 5 条三处同批改为「接进 `_split_tail()` 的 await 链(`:40-44`)」并写明失败机理与段内自持 instantiate/queue_free 的先例形态——**我回读 `system_test.gd:26-28`/`:35-48`/`:213-217` 确认成立**,`:40` 行尾注本身就记着这条教训 |
| 4 | 同上 | 四消费方行号偏一:卡写 `:72`/`:76-78`/`:82`,实为 `:73`/`:79-80`/`:83`(`:129` 对) | 自判 | §3.2 与 R3 两处改正——我逐行打开 `main_overlay_flow.gd:69-83`/`:125-129` 核实 |
| 4 | 同上 | R5② 把「营地场景根代码 new」引到 `camp_scene_view.gd:13-14`,该行实为命中区名表 `_HOTSPOT_NAMES`;真正的 new 在 `scenes/camp_screen.gd:13` | 自判 | R5② 改引 `game/presentation/scenes/camp_screen.gd:13-14` 并补 `camp_screen.tscn` 根锚 preset=15 的承重事实——我回读两文件确认 |
| 4 | 同上 | R3 括注「`modal_shell()` 产 VBox+HSeparator」不实:HSeparator 是弹窗自造(`confirm_dialog.gd:26`),该壳不产横排 | 自判 | R3 括注改为「产 CenterContainer+PanelContainer+VBox,不产横排;HSeparator 系弹窗自加」——回读 `confirm_dialog.gd:26` 与 `ui_kit.gd:509-525` 确认 |
| 4 | 同上 | T3.3/§12 称 `confirm_dialog.gd:27-29` 为「容器右对齐先例」,而 `:29` 实为 `ALIGNMENT_CENTER`——是同机制先例、不是右对齐先例 | 自判 | 两处措辞改正,并明写本件同处取 `ALIGNMENT_END` 才是右对齐(免得实现误认现成右对齐件) |
| 4 | 同上 | R6/T3.5 引「§8.4」未冠文档名,卡内 §8 无 8.4 小节,易读作自引 | 自判 | 改为「test-conventions §8.4(正面效力自检)」 |
| 4 | 同上 | R4 判据读 `main._confirm_consumer`(私有),与 §12「不读私有成员」的自陈口径不一;但探针面先例在案、封装扫描件射程不含探针 | 自判 | R4 明写主证=`run_scope.is_adventure` 翻转,私有一读注为探针既有先例(`ui_click_probe.gd:272`/`:286` 现役直读),并记扫描射程(`presentation_encapsulation_sweep_test.gd:80-94` 的 `root\._` 规则只套在五个 flow 件上,`main.gd` 那格取 false)——**其路径写法有误**(该件在 `game/tests/unit/presentation/`,不在 `unit/contracts/`),结论经我回读不受影响 |
| 4 | 同上 | §14 出口职责句「返回句柄供顶栏件摆放徽章」与 T3.2 实际丢弃返回值、摆位归容器不符 | 自判 | 职责句改为「供调用方读取与断言」,并明写摆位不由该出口负责(归 T3.3 的容器) |
| 4 | 同上 | T3.0 只把「徽章自高≠48」归因于描边 1px,漏了第二条成因:徽章内 Label 取 18px 档(`ui_kit.gd:648`→`:438` `FS_SUB=18`),行高若高于 32px 图标则最小高由文字决定 | 补写 | T3.0 与 L3 第 5 条两处成因并列;处置强度不变(实测+≠48 即停机呈报)——回读 `ui_kit.gd:638-656` 确认该 Label 用 FS_SUB |
| 4 | 同上 | R2 的判据(`is_adventure`+`level_screen.visible`)不是件1 改动特有的面,改了也可能不红 | 补写 | R2 格内明写「本行是开局终态在位断言,被测改动的特有提交面由 R1 承载;`is_adventure` 既有探针已断(`ui_click_probe.gd:704`)」,两行同批缺一即红 |
| 4 | 同上 | 待办清单本条实况仍写「两轮独立复核报告」,现为三轮+本轮 | 补写 | 待办清单实况行随本轮改卡同批更新(写卡段 owns 该条目状态与实况,非实现批动作) |
| 4 | 同上 | 收编版残留扫描:无一处把收编/通用出口/color·pass_input 形参/R9/改 `ui_assembler` 写成现行方案;历史叙述均带作废标记;T3.0–T3.7、R1–R8、白名单 1–6、L3 1–5、裁决史①–⑤ 交叉引用零悬空 | 自判(确认留档) | 无需改;核法=全文逐节比对+按符号 grep 残留 |
| 4 | 同上 | 行号核对:40 处引用逐行打开无误(`ui_kit.gd` 17 处、`camp_hud_band.gd` 6 处、`confirm_dialog.gd` 6 处、`camp_scene_view.gd` 5 处、`main.gd` 8 处、presenter 2 处、装配链与注册面、两份基线脚本、五份文档锚点) | 自判(确认留档) | 无需改——注意该「无误」不含本表第 3、4 两条(它们正是被推翻的例外) |
| 4 | 同上 | 引擎语义:未入树节点调 `set_anchors_preset(FULL_RECT)` 的四边 offset 归零、铺满宿主,与现役 `_modal_dim()`/`overlay_bg()` 同形,R5② 的 1280×48 成立;顶栏件 1280 宽由 `ui_registry.gd:61` 的 FULL_RECT 注册撑出 | 自判(确认) | 无需改判据;按建议在 T3.4 补一句「出口须在 `_init()`(入树前)调用」的时机理由 |
| 4 | 同上 | `Color(常量, α)` 的 const 派生在库内大量现役;const 引用同文件 const 的写法 grep 零先例,卡内凭 11-06 临时工程实测(仓库无产物可复验) | 自判(确认,标风险) | 维持卡内实测句,不另设断言;该写法若失配属编译期 fail-fast,不会静默绿 |
| 4 | 同上 | 契约面与外部一致性:契约4/契约5/§5 不做行三者无矛盾无空隙;`game/tests/README.md` 两行新增能力名与 §8 能力行列逐字一致;§13 预算实算正确(`ui_kit` 29 个 static func 减 6 个私有=23→24;`main.gd` 32 持平;tests 不在 gdstyle 射程;palette 只匹 `Color8(`) | 自判(确认留档) | 无需改 |
**写卡段对轮次 4 的不采信项**:1 条——它把 `presentation_encapsulation_sweep_test.gd` 记在 `game/tests/unit/contracts/` 下,实际在 `game/tests/unit/presentation/`;该错的只是路径,其结论(扫描射程不含探针、`root._` 规则只套 flow 件)经我回读 `:80-94` 成立,已按正确路径写进 R4。
**轮次 4 总判与现状态**:两条硬伤与四处事实错已全部落卡,四条一致性问题与三条补写同批落定,未新增待裁点。**本卡的终态设计(一个具名单参出口、零收编)至此经第四轮独立复核并闭合,零待裁点,开工门=U0(用户批卡)。**
+35
View File
@@ -2,6 +2,41 @@
本清单是流水线的唯一登记处:以后才做的事在此登记一条,随流水线段推进改状态,做完整条删除(条目记进度,不是各段的开工前置);各系统文档的「待办」节只留一行指路存根,不再自建条目。条目格式(标题=登记元数据含可选优先级,正文=实况/缺口/改动面/状态四属性)与状态机以 [doc-conventions §12.1](design/engineering/doc-conventions.md) 为权威。
#### 流水线闸认锚式不含中文名文档——判据出处行锚对半数现行文档失效(2026-11-05 登记,来源=批次移交)
**实况**:判据出处行锚的机检式 `ANCHOR_RE`(`tools/pipeline_gate.py:68`)字符类=`[A-Za-z0-9_\-.\\/]`,不含中文段——凡验收判据句落在中文名现行文档(本库 GDD 多为此形态:`HUD框架.md`/`关卡节点地图.md`/`待办清单.md`),机检一律认不到锚、判「判据出处行锚缺失」红。
- 批次实证 reports/需求卡片-营地交互修复批-2026-11-05.md:R2/R3/R4/R8 四行的真出处是中文名文档,只能另挂一个 ASCII 路径文档当替身锚才过闸
- 发现与依据 reports/复核-营地交互修复批-2026-11-05.md 第 22 条(`tools/pipeline_gate.py:68`)
**改动面**:工具代码
**状态**:待执行
#### 层序落位单口检查的扫描面不含子目录——视图层插位不在该闸视野(2026-11-05 登记,来源=会话提及)
**实况**:契约件 `game/tests/unit/contracts/source_guard_test.gd` 的「V1d 层序落位单口」用平铺列目录(`:86-99`,只收 `.gd` 文件名、不递归),注释 `:85` 仍写「presentation 无子目录」;而 `game/presentation/` 现实有 `views/` 与 `scenes/` 两目录,视图层全部文件不在该闸视野内。
- 现状读数:全 presentation 的 `move_child` 共三处——合同函数 `apply_layer_contract()`(定义在该函数的落位件内)体内两处属唯一合法口;`game/presentation/views/ui_kit.gd:841` 在漏网区,是卡片内部布局重排、非模态层序,故当前无漏网真违规
- 规则文本出处:`main_ui_build.gd:122`/`:156`/`:272`「插位由 LAYER_CONTRACT 槽统一落位——禁散落 move_child」
- 启动待裁点(本条不预裁):是否真要把两目录纳入扫描面尚未确定;若纳入,判据须先收窄到「禁对根容器插位」,否则组件内重排会误红
**改动面**:工具代码
**状态**:待执行
#### 营地交互修复批——大门无断点开局被开始层盖住/确认框钮序/营地顶栏无栏体(2026-11-05 登记,来源=会话提及)
**实况**:三件同批一张需求卡片,对照表内一件一行。
- 需求卡片 reports/需求卡片-营地交互修复批-2026-11-05.md
- 四轮独立复核报告 reports/复核-营地交互修复批-2026-11-05.md
- 设计定稿 design/gdd/ux/camp.md v2.8 §顶栏、design/gdd/systems/表现与支撑/HUD框架.md §提示与弹层、design/art/art-bible.md v3.43 §6.2
- bug 证据①被开始层盖住:`camp_shop_presenter.gd:85` 显层 → `main.gd:211-212`/`223-224` 先关营地再开局 → `main.gd:292` 不隐藏;该动线测试与探针零覆盖
- bug 证据②否左是右:`views/confirm_dialog.gd:31-39` 加入序=取消→次→确认
- bug 证据③无可见栏体:`views/camp_hud_band.gd:10-17`(件已装配落座,缺栏体底与落座定值)
**改动面**:文档+游戏代码
**状态**:文档设计已闭合+已写卡
#### 数值标定窗口总挂账——原九条数值类条目合并(2026-10-28 登记,来源=会话提及)
**实况**:九条数值类挂账合并一条(削弱档位终值/迭代 10 奖励重构联动/调参点评登记/三方向解锁清单与定价/GP 经济换算失衡/天赋树欠账余两件/商店刷新两参数/基线通关率越带杠杆扫描/成长系数节奏),逐条明细与统一执行形态(窗口内一次 MC 批量覆盖全冒险期望+奖励期望)全载 reports/汇总-数值标定窗口挂账-2026-10-28.md。共同裁定:未设计不启动,重启条件=用户发令开数值标定窗口。MC 档位硬闸见 sim-data/README.md「MC 采集档位表」。