写卡改判(营地交互修复批·件3 终裁落卡+轮次4 独立复核): 撤掉「铺满色面收成带形参的通用出口并收编三处同形旧实现」那一版设计, 落成用户 11-06 终裁形态——公共件一个具名出口 UiKit.camp_hud_band_surface(host) 形参只 host、色值 CAMP_HUD_BAND=Color(CAMP_HEADER_BAND,0.80)/PRESET_FULL_RECT 铺满/MOUSE_FILTER_IGNORE/挂宿主/返句柄全写死体内, ui_assembler.gd:224-230、ui_kit.gd:486-491、:537 三处同形写法不收编不动(形状撞车≠同一件事: 遮罩遮挡语义/页面底色档位/HUD 带定值三个变化原因, 绑起来即既不内聚又不低耦合且为没到来的问题做设计); R9 等值回归删、验收回 R1–R8、估时 2.25–2.5→2.0 工作日(无收编无两次全档), 契约4 加「禁开 color/pass_input 形参+禁收编」双禁、契约5 补 ColorRect 默认 STOP 漏设不报错的旁证, §15 Q1 裁决史补③④⑤(含 Q4 消解——用户否定的是该呈报前提而非某一案), §12 末段留两版作废判据的合成理由; 轮次4 由第四个未参与撰写只读子代理复核终态, 17 条: 硬伤 2(R4「按行矩形左位」必打空——行 ALIGNMENT_CENTER 且双钮可见宽 444<壳宽 460, 改取 child(0) 全局矩形中心; _smoke_camp_hud_band 接 _initialize 不成立——只调 _split_tail 且尾段 quit, 不被 await=静默不执行=假绿, 改接 _split_tail await 链)/事实错 4(四消费方行号 72/76-78/82→73/79-80/83、场景根 new 位置 camp_scene_view:13-14→scenes/camp_screen.gd:13-14 并据此推翻轮次3 沿用值、modal_shell 不产 HSeparator、:27-29 是同机制先例非右对齐先例)/一致性 4(§8.4 冠名 test-conventions、R4 读 main._confirm_consumer 注明探针先例 :272/:286 与扫描射程、§14 职责句去「摆放徽章」、R2 注明特有提交面由 R1 承载)/补写 3(徽章自高第二成因 18px 行高 FS_SUB、T3.4 补入树前调用时机、待办清单实况两轮→四轮)/确认 5(收编版残留零、40 处行号、FULL_RECT 铺满与 1280 承重链、const 派生合法性、契约面与 README 能力行逐字一致), 未新增待裁点; 不采信 1(复核者把 presentation_encapsulation_sweep_test.gd 路径误记 unit/contracts/, 实在 unit/presentation/, 结论经回读成立已按正确路径落卡); 本步凭据: pipeline_gate 直跑 PASS(待办条目 27/卡片口径 2 张全过)+tools/run_all_gates.sh --docs exit=0「验收通过, 闸况与基线一致无新增红」(基线 4a650d0e); 待办清单本条状态仍 文档设计已闭合+已写卡, 零待裁点, 开工门=U0 等用户批卡, 未合并未推送

This commit is contained in:
DKChan committed 2026-11-06 01:38:27 +08:00
1 parent 4a650d0ed3
commit 0977a548bf
3 files changed
+170 -66

No files matched your search

@@ -59,4 +59,51 @@
| 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 总判:三条补写已落卡,一条确认留档,一条按自判落并向用户报备。落卡后本卡零待裁点,可提交(合回仍等用户发令)。
轮次 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(用户批卡)。
@@ -42,7 +42,7 @@
预览人审在案: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 裁「按放在公共区域的这一层」):`ui_kit.gd` 新增一枚带透明度的派生常量 `const CAMP_HUD_BAND := Color(CAMP_HEADER_BAND, 0.80)`——红绿蓝三分量继承既有 token、α 只此一处,顶栏件引用它。两件事已实测(引擎 4.7.2,工程外临时工程跑通后即删):①这种「const 作构造参数派生 const」的写法编译通过,`to_html(true)` 读数为 `6e4526cc`、三分量与母 token 逐一相等;②**色道存单精度浮点,`.a == 0.80` 判为 false**(实测 `a=0.80000001192093`)——所以断言一律写成 `to_html(true) == "6e4526cc"` 或与同构造值整体等值比较,禁写 `.a == 0.80`,否则实现正确而断言红,最容易的自救就成了放宽阈值(触 test-conventions §8.5 禁止削弱测试)。
顶栏这块带子的落点定稿(用户 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 禁止削弱测试)。
---
@@ -62,7 +62,7 @@
- `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:76-78`(「继续上一段冒险」/「开始新冒险」/「取消」)、大门无断点 `main_overlay_flow.gd:82`(「是」/「否」)、篝火离场 `main_overlay_flow.gd:72`(「离开」/「留下」)。
- 四处消费方(全部经同一件):删档确认 `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——顶栏件有装配无栏体
@@ -71,7 +71,7 @@
- 徽章现状:`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`)。
- 铺满矩形的既有实现盘上已有两份、形态不同:`game/presentation/ui_assembler.gd:224-230` `overlay_bg(host, color) -> ColorRect`(**外部调用者零**,仅被该文件自身 `:100`、`:214` 用)与 `game/presentation/views/ui_kit.gd:486-491` `_modal_dim()`(私有,仅 `:511` 一处用)。四处同形的用途实为三种意图——亮底面板(`BG_BRIGHT`)/模态压暗遮罩(黑 0.6)/tooltip 遮罩底,本批顶栏带是第四种意图(常驻 HUD 条且不吃点击)。**本批不复用那一份、也不抽新工厂**(依据与留痕见第 12 节与第 15 节);顶栏件按 `views/` 现行形态自己新建矩形——该目录直接 `ColorRect.new()` 的现存先例共 8 个文件 15 处(`battle_end_overlay.gd` 4 处、`board_fx_view.gd` 3 处、`camp_scene_view.gd` 1 处等)。
- 盘上「新建 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 锚,该面等价证据=探针/单元断言+实机目检。
@@ -80,11 +80,11 @@
## 4. 设计契约(红线,违反=L3 停机呈报)
- 🔴 **契约1|冒险启动路径的隐藏点收一处**:**限「开局」与「续玩」两条路径**——隐藏责任只许落在 `_start_adventure()`(开局)与 `_resume_from_menu()`(续玩)两个函数内部。第 3.1 条的先例形态即本契约依据。**本契约不管其余开层自管点**:全库开始层显隐共 12 处(`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`),那些是选档层/生涯页/终局回菜单等各自开合面的自管句,本批一律不动、也不受本契约约束。禁再新增**开局或续玩路径**上的第三处隐藏点,禁把隐藏写回 gate 出口(调用方)。
- 🔴 **契约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|取色单点在 UiKit,禁视图内裸写色值**:栏体色=`ui_kit.gd` 新增的派生常量 `CAMP_HUD_BAND`(`Color(CAMP_HEADER_BAND, 0.80)`,三分量继承在册 token),顶栏件与断言都只引用它;**禁在视图件写 `Color8(110, 69, 38)` 类裸值、禁把 α 写在视图里**。禁的是新增**语义色**,不是禁止派生常量——同文件在册先例:`HP_BAR_TRACK`(`ui_kit.gd:200`,注「视图原裸值收口单点——非色板新增」)、`TOAST_BG`(`:189`)与 `TIP_BG`(`:190`)都是带 α 的派生常量。依据=`ui_kit.gd:2` 文件头「呈现层共享小部件工厂+全站取色/描边唯一出口——各视图禁内联 Color8/StyleBoxFlat 字面量,换皮只改本文件」。色板基线不受本枚常量影响:`tools/gen_palette_baseline.py:42` 只正则 `Color8(数字,数字,数字)`,带 α 的 `Color(...)` 形态从不进快照。
- 🔴 **契约5|栏体不挡命中**:栏体 ColorRect 必须 `mouse_filter = Control.MOUSE_FILTER_IGNORE`,顶栏件自身 `camp_hud_band.gd:13` 的同款设置是既有锚。漏设=48px 带内的点击被栏体吃掉,与 `camp.md:37` 禁区纪律叠加成「顶排物件点不动」。
- 🔴 **契约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 取证。
@@ -95,7 +95,7 @@
**做**:
1. `_start_adventure()` 入口收一个隐藏点,摘掉 `main.gd:194` 的冗余句;
2. `ConfirmDialog` 三颗钮的 `add_child` 次序整体镜像;
3. `ui_kit` 加一枚带 α 的派生色值常量 + `CampHudBand` 用它新建可见栏体、徽章改右对齐容器顶格落座;
3. 公共件出一个具名出口封装这块带子的全部外观(色值与 α、铺满、不吃点击、挂上宿主、返回句柄)+ `CampHudBand` 改调该出口、徽章落座改右对齐容器;
4. 上述三件各自的测试(对照表 8 行 R1–R8)+能力清单两行(写卡段已落)+回归面确认。
**不做(含去向)**:
@@ -105,6 +105,7 @@
| 「破坏性确认与常规确认禁止同位」(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` | 启动默认态,与三件无关 | 无 |
@@ -136,15 +137,15 @@
|---|---|---|---|---|
| `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` | 呈现层共享工厂与全站取色单点 | 改动(新增一枚带 α 派生常量 `CAMP_HUD_BAND`;**不新增方法**) | 行为改动(顶栏呈现的数据源) | R5、R6 |
| `game/presentation/views/camp_hud_band.gd` | 营地顶栏 HUD 件 | 改动(新建栏体矩形引用该常量+徽章落座改右对齐容器) | 行为改动 | R5、R6 |
| `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()`,接进 `_initialize()`) | 非行为改动(测试面) | R5、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 节「落位与可复用性预检」互指:改动件四个、新增件仅一枚单元套;顶栏矩形为何不复用盘上现成那两份、也不抽新工厂,理由见第 12 节与第 15 节的留痕句。
结构图与第 12 节「落位与可复用性预检」互指:改动件七个(四件表现层+三件测试面)、新增件仅一枚单元套;这块带子的全部外观收在公共件的同一个具名出口里,出口只服务这块带子(判据见第 15 节 Q1 裁决史④与契约4)。
---
@@ -153,11 +154,11 @@
| 行 | 需求点(判据出处行锚) | 改动(文件:行/行为) | 验收测试(名称+落点+尾缀) | 层级 | 真实入口 | 判据绑定面 | 能力行 |
|---|---|---|---|---|---|---|---|
| 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`(停点呈现面,非终态推断) | 既有:营地大门两分支确认与断点续玩接线 |
| 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:72/76/82/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()` 产 VBox+HSeparator,`ui_kit.gd:509-525`;`UiKit.button()` 无子节点)。判据面=树的公开子节点序(同 `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` 打按钮行左位中心坐标) | 探针 | 弹窗开态下按按钮行实际矩形算左位坐标真点 | `_confirm_consumer` 在真点前为 `"gate_new"`、真点后走开局分支(`run_scope.is_adventure` 翻转+`_confirm_consumer` 清零)——位次改动若错接,坐标命中的将是「否」,该面即红 | 新增:确认弹窗按钮位次与语义同钉 |
| R5 | 件3 顶栏栏体几何与徽章落座(`design/gdd/ux/camp.md:41`) | `camp_hud_band.gd:10-17` 新建栏体矩形引用新常量+徽章落座改右对齐容器;`ui_kit.gd` 加 `CAMP_HUD_BAND` | `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:51`),走 `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 节实测句);②栏体矩形铺满:`size == Vector2(1280, 48)`;③`mouse_filter == MOUSE_FILTER_IGNORE`;④栏体是顶栏件的**第一个子节点**(子节点序=绘制序,色面必须先入才不盖徽章);⑤徽章全局矩形 `position.y == 0` 且 `end.x == 顶栏全局矩形 end.x − 12`(x 向缺判据则位次改错仍绿,故与顶格同批配齐)。前置量测=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;扫描面非空前置照 §8.4 正面效力自检配齐。**禁把视图件的 color 直接当预期值喂进算式**(那是 oracle 镜像,test-conventions §8.7 判红) | 新增:营地顶栏栏体定值与落座 |
| 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 | 既有:营地大门两分支确认与断点续玩接线 |
@@ -194,28 +195,29 @@
产出:位次成为规格钉死的呈现定值,推进钮恒为该按钮行的 child(0)。
### T3|营地顶栏可见栏体(≈0.75 工作日)
### 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`);`Control.PRESET_FULL_RECT`/`Control.MOUSE_FILTER_IGNORE`(引擎枚举,栏体铺满与不吃命中的既有形态见 `camp_hud_band.gd:11-13`)。
取用:`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))` 推得 32+8+8=48,但 `border_w=1` 是否计入最小尺寸未证实——**这是推导,不是实测量**)。读数=48 → 按 T3.2 顶格落座;读数≠48(如 50)→ 停步走第 10 节 L3 第 5 条呈报,禁自行改栏高或改徽章内边距。读数与取数时机一并写进实现报告。
- [ ] T3.1 实装(**Q1 已裁·2026-11-05 用户裁「按放在公共区域的这一层」**):先在 `game/presentation/views/ui_kit.gd` 的色板段(`CAMP_HEADER_BAND` 定义在 `:195`,同文件带 α 先例见 `:189`/`:190`)新增 `const CAMP_HUD_BAND := Color(CAMP_HEADER_BAND, 0.80)`,注记沿 `HP_BAR_TRACK`(`:200`)的「视图原裸值收口单点——非色板新增」说法。再在 `game/presentation/views/camp_hud_band.gd` 的 `_init()` 内、挂徽章**之前**新建栏体矩形:`ColorRect.new()` + `color = UiKit.CAMP_HUD_BAND` + `set_anchors_preset(Control.PRESET_FULL_RECT)` + `mouse_filter = Control.MOUSE_FILTER_IGNORE`(契约5)+ `add_child`——顶栏件自建是该目录现行形态(8 个文件 15 处先例,含本件自己的徽章),**不复用 `ui_assembler.gd:224` 的 `overlay_bg()`**(它的头注 `:2-3` 把服务对象写成「供组合根接线」,且外部调用者零;视图引它会新开一条 `views → ui_assembler` 路径),**也不抽新工厂**(意图三分,见第 12 节留痕句)。子节点序即绘制序,故栏体必须先入、徽章后入。
- [ ] T3.2 实装(**Q2 已裁乙·2026-11-05 用户裁**):徽章落座改为「栏体内加一层右对齐容器」——新增 `HBoxContainer` 铺满栏体(`set_anchors_preset(Control.PRESET_FULL_RECT)` 之后置 `offset_right = -12.0`)、`alignment = BoxContainer.ALIGNMENT_END`、`mouse_filter = Control.MOUSE_FILTER_IGNORE`,徽章作该容器子件、由容器摆位,余额位数增宽时自然向左展;替换 `camp_hud_band.gd:15-16` 现值(`PRESET_CENTER_RIGHT` + `position=(-160, 8)`,系无栏体时代把 x 写死的代拍板)。容器右对齐先例=`confirm_dialog.gd:27-29`(HBoxContainer+alignment 摆位,非手算偏移)。内缩定值 12px 不变(白名单第 3 条)。
- [ ] T3.3 验收:`game/tests/system_test.gd` 新增 `_smoke_camp_hud_band()` 并接进 `_initialize()`,实现 R5 的五项判据(色值走 `to_html(true) == "6e4526cc"` 或整体等值比较,**禁浮点分量直等**;`size == Vector2(1280, 48)`;`mouse_filter == MOUSE_FILTER_IGNORE`;栏体是顶栏件的第一个子节点;徽章 `position.y == 0` 且 `end.x == 顶栏 end.x − 12`)。
- [ ] T3.4 验收:`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.5 验证:新增两测先行孤立跑绿,再并入 `--code` 全套;营地屏截图面由 `render_gate` 的七屏段随批产出,作 R5/R6 的对照取证。
- [ ] T3.6 目检登记:营地顶栏观感(「成一条可辨窄带、徽章落在带内」)写进实现报告实机目检总清单,登记即完成义务。
- [ ] 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 目检登记:营地顶栏观感(「成一条可辨窄带、徽章落在带内」)登记一行进实现报告实机目检总清单,登记即完成义务。
产出:`CampHudBand` 成为顶栏唯一呈现件(栏体色面+右对齐容器+徽章),顶栏色值单点=新增的 `UiKit.CAMP_HUD_BAND`(其三分量继承 `CAMP_HEADER_BAND`,α 只此一处)。
产出:`CAMP_HUD_BAND` + `camp_hud_band_surface()` 是这块带子外观的唯一出处(同文件相邻两段);`CampHudBand` 的外观=该出口+右对齐容器+徽章三件,视图内无一处自建 ColorRect;盘上三处同形写法原样未动。
### T4|产出物落位卡(≈0.5 工作日,末卡)
- [ ] T4.1 代码域全档全绿后、合并前写 `reports/iter<53>-实现报告-<日期>.md`:各卡状态+实机目检总清单(含 T3.6)+遗留读数义务+实现决定记录(超白名单的微决策逐条登记)。
- [ ] T4.1 代码域全档全绿后、合并前写 `reports/iter<53>-实现报告-<日期>.md`:各卡状态+实机目检总清单(含 T3.7)+遗留读数义务+实现决定记录(超白名单的微决策逐条登记)。
- [ ] T4.2 写 `reports/iter<53>-反哺点-<日期>.md`:第 6 节每条命中项都要有落点(哪一节、改成什么、依据什么);无命中也要写「本批零反哺点」并附核过哪几处。
- [ ] T4.3 核对 `game/tests/README.md` 两行新增能力名与实际落地函数名逐字一致(名实不符=停卡退回写卡段)。
- [ ] T4.4 呈报合回清单,等用户发令再走收口(冻结→件核→并 master→重塑→删区)。
**估时合计 ≈1.75–2.0 个工作日**。切分预案:T3 若因取样件超 0.25 日未完,先合 T1+T2(两件互不依赖),T3 另起一批——第 1 节三件本无耦合。
**估时合计 ≈2.0 个工作日**(T1 0.25+T2 0.5+T3 0.75+T4 0.5)。T3 的 0.75=出口一枚(十行内)+顶栏件改两处(调出口+落座容器)+两条新测+孤立验证。无收编、无等值回归、无两次全档义务。
---
@@ -228,7 +230,7 @@
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 若计入最小尺寸则推得 50)=「顶格落座」在 48px 栏内放不下,第 2 节与 `camp.md:41` 的推导句失效,停步呈报,禁自行改栏高、改徽章内边距或放宽 R5 判据。
5. T3.0 量得徽章 `get_combined_minimum_size().y` ≠ 48(描边宽 1px 计入、或 18px 文字行高高于 32px 图标使最小高由文字决定,两条都会推得 >48)=「顶格落座」在 48px 栏内放不下,第 2 节与 `camp.md:41` 的推导句失效,停步呈报,禁自行改栏高、改徽章内边距或放宽 R5 判据。
---
@@ -238,8 +240,8 @@
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()` 在 `_initialize()` 内的插入位(不改变既有段序)。
6. 新色值常量的命名(卡内暂定 `CAMP_HUD_BAND`)——只要它是「一枚带 α 的派生常量、不加方法、不进色板五件表」这个形态已定,名字可由实现定;若实现改成加方法或加语义色,触契约4 与第 13 节,属 L3 呈报。
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 呈报。
@@ -249,14 +251,14 @@
| 新增/改动件 | 复用面(盘上已有什么) | 唯一面 | 分层与交互面 |
|---|---|---|---|
| 栏体矩形(T3.1,Q1 已裁) | 盘上已有两份同形实现:`ui_assembler.gd:224-230` `overlay_bg()`(**外部调用者零**,仅该文件自身 `:100`/`:214` 用)与 `ui_kit.gd:486-491` `_modal_dim()`(私有,仅 `:511` 一处用)。本批两份都不复用、也不抽新工厂,按 `views/` 现行形态自建(该目录直接 `ColorRect.new()` 有 8 个文件 15 处先例,含本件自己的徽章)。不引装配器的依据:它头注 `:2-3` 把服务对象写成「返回句柄供组合根接线」「接线拓扑唯一归组合根」,现网引用方全在组合根与屏壳侧(`main_ui_build.gd:7`、`scenes/adventure_screen.gd:21`、`scenes/menu_screen.gd:15`),视图引它等于新开一条 `views → ui_assembler` 路径。**不抽工厂的留痕句见本节末** | 顶栏呈现件唯一 = `CampHudBand`;色值单点 = 新增的 `UiKit.CAMP_HUD_BAND`(`Color(CAMP_HEADER_BAND, 0.80)`,三分量继承在册 token、α 只此一处),视图与断言都引用它,禁在别处出现第二组「同一色+同一 α」 | 呈现层内;读数仍经 `camp_data()` 投影单口不变(`camp_hud_band.gd:26-27`),本批零新增跨层引用路径 |
| 顶栏带外观出口(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.2) | 已有做同样事的东西:`HBoxContainer` + `alignment` 摆位(`confirm_dialog.gd:27-29`)——**Q2 已裁乙(2026-11-05 用户裁)**,采容器右对齐形态;另两案(锚点生长、`size_updated` 回调)作淘汰留档见第 15 节 | 内缩值 12px 只在落座一处出现一次,禁在断言里另写第二套推导 | 呈现层内 |
| 徽章落座(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`/`camp_scene_layout_test.gd:_test_hud_band_contrast_over_bg`(T3.3/T3.4) | **扩展**既有套件,不新建宿主;取样法复用 `terrain_tile_sets_test.gd:105-107` 的双层全扫+`get_pixel` 路径 | 几何判据落系统测试、对比判据落布局单元套——两处职责已由套件名界定,禁第三处重复断言 | 测试层 |
| `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` 路径 | 几何判据落系统测试、对比判据落布局单元套——两处职责已由套件名界定,禁第三处重复断言 | 测试层 |
**同形不同意图的留痕句(本卡有意接受这份重复)**:铺满一个控件的纯色矩形这件事,盘上已有两份实现、四种用途——亮底面板(`ui_assembler.gd:100` 用 `BG_BRIGHT`)、模态压暗遮罩(`:214` 用黑 0.6)、tooltip 遮罩底(`ui_kit.gd:486`),与本批的常驻 HUD 条带。三次法则的触发条件是「同一功能第三次出现」,此处是同一**形状**第四次出现、同一**意图**第一次出现,故不抽公共工厂;把它抽成一个件得到的只会是"随便铺个矩形",属形状公因数而非概念。若日后出现第二个**同意图**件(又一个常驻 HUD 条带),再行提取。该取舍按 Fowler 技术债四象限属「有意且审慎」一格,凭据即本句+实现报告的实现决定记录。(本句由用户 2026-11-05 的架构取舍口径定:体量未变、矛盾未现,不为未到来的问题预先设计。)
**为什么出口只服务这块带子(2026-11-06 用户终裁;本段取代本卡此前两份互相矛盾的留痕句——「接受第四处重复故不抽工厂」与「四份同形收成带形参的通用出口」)**:用户裁的是两件事的合成。①**一个物件的外观不得拆两处**——色值、α、铺法、点击、挂载这五件事必须在同一个出口内定义,不许「常量在公共件、矩形在视图」;那等于要求每个改它的人同时记得两处,漏一处就得到一个自相矛盾的物件。本会话确有改漏实例:同一组色值要在两份文档里成对改,卡内同步面还写了「禁单改一处」的防呆,却在代码面上造出另一个新的成对结构。②**抽不抽公共器不由形状撞车决定**——不得为了「全仓只剩一处 ColorRect 铺满」这种读数好看,把遮罩、页底、HUD 带三个变化原因绑进一个带形参的通用器;那既不内聚(一个函数回答三个不相关的问题)也不低耦合(改顶栏带要回归全站弹窗底与两个全屏页),而这三处今天都没有待改的东西。**早先那份「三次法则、意图未第三次出现故不抽工厂」的留痕句,其动机经用户点破是「少动文件」而非纪律,作废**;但据此反弹出的「整案收编+形参化点击语义」同样作废。代价面(`ui_kit` 公开方法 23→24 须修订登记基线)见第 13 节例外申报;回归面因不收编而留在本件射程内,估时相应回落。
---
@@ -273,38 +275,43 @@
| 文件 | 基线登记(`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 持平 ✓。色板快照面也不动:`tools/gen_palette_baseline.py:42` 只正则 `Color8(数字,数字,数字)`,带 α 的 `Color(...)` 常量从不进快照(同文件 `TOAST_BG`/`TIP_BG` 即此形态) |
| `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/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. 拆分边界纪律
本卡非拆分/收敛/重构类:**不适用**——零拆出单元(无新私有函数族、无新件从存量文件迁出、无段件/状态件),唯一新增是一个视图单元套件,其职责语句=「钉确认弹窗的按钮位次与语义绑定」,单一变化原因=位次定值变更(第 12 节复用面同载)。code-conventions §1.1 拆分判据与本节互指,实现期若发现需要拆 `camp_hud_band.gd` 或 `main.gd` 才落得下,属卡片未预见的结构动作=L3 呈报,禁为凑绿硬拆。
本批新增的可复用单元只有公共件里那一个出口函数,故本节条款的适用面=该出口,判据权威=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. 待裁点(复核产生,两条都合规、代价不同——设计权归用户)
## 15. 待裁点(三轮复核产生;Q1 因写卡段自决被驳回而重开过、又因出口的执行形态被再裁一次——全程留痕)
独立复核(未参与撰写的只读子代理)把本卡打回一次,四条闭合里三条由写卡段按权威文档自决落卡,第 4 条拆成两案呈用户裁决。**两案现已裁尽,本卡零待裁点,开工门=U0(用户批卡)。** 以下留档=各案备选、代价与裁决,供复核与编排段比对,不再重开。
独立复核(未参与撰写的只读子代理)三轮:轮次 1 打回一次,四条闭合里三条由写卡段按权威文档自决落卡,第四条拆成两案呈用户裁决;轮次 2 抓到「矩形谁建」这条轴属越权自决;轮次 3 抓到收编版四处硬伤并生成 Q4。**当前状态:Q1/Q2/Q3 已裁尽,Q4 因 11-06 用户再裁而消解(不再是一条分叉),本卡零待裁点,开工门=U0(用户批卡)。**
### Q1|栏体这一面从哪来——**已裁(2026-11-05 用户裁「按放在公共区域的这一层」)**
### Q1|顶栏这块色面从哪来——**已裁(终态=公共件一个具名单参出口,同形旧实现一律不动)**
事实底座:`UiAssembler.overlay_bg(host, color)`(`game/presentation/ui_assembler.gd:224-230`)确实做了「ColorRect + PRESET_FULL_RECT + add_child + 返回句柄」这四步,语义就是「铺满宿主的色面」。但该文件 `extends RefCounted`、**无 `class_name`**,现网一律 `const UiAssembler := preload("res://presentation/ui_assembler.gd")` 引用(`main_ui_build.gd:7`、`scenes/adventure_screen.gd:21`、`scenes/menu_screen.gd:15`),**引用方全在组合根与屏壳侧,`views/` 目录零先例**;而 `views/` 内直接 `ColorRect.new()` 有先例(`views/battle_end_overlay.gd:261`/`:289`/`:314`)。
事实底座:`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`。
| 案 | 做法 | 代价 |
|---|---|---|
| 甲 | `camp_hud_band.gd` 加 `const UiAssembler := preload(...)`,调 `overlay_bg(self, Color(...))` | 复用现成件、零重复实现;但给 `views/` 开一条此前零先例的装配器引用路径(该文件头注自陈「接线拓扑唯一归组合根——本类零信号连接」,被视图件引用属越界用法) |
| 乙 | 视图内 `var band := ColorRect.new()` 四行自铺 | 与 `views/` 既有形态同构、零新路径;代价是重复装配器已有的四行(第 12 节要申报「为什么不能复用那一个」) |
当时并列过的案与代价:甲=顶栏件 preload 装配器复用那一个出口(零重复,但给 `views/` 开一条该目录零先例的引用路径,且该文件头注自陈「接线拓扑唯一归组合根」);乙=顶栏件自建(与 `views/` 现状同构,但重复四行,且色值与铺法分居两处);丙=公共件出一个出口(真「整件外观一处定义」,代价是 `ui_kit` 公开方法 23→24 要修订登记基线)。
呈裁时并列三案(甲=视图引装配器、乙=视图内自建矩形、丙=提到公共件层);裁决过程中又查实一条规范原文——`ui_kit.gd:2` 文件头「全站取色/描边唯一出口——各视图禁内联 Color8/StyleBoxFlat 字面量,换皮只改本文件」,它把"色值放哪"与"矩形谁建"这两件事分开了。
> **裁决(2026-11-05 用户裁「按放在公共区域的这一层」)**:取**丙的取值面+乙的动作面**——色值与 α 做成公共件里的一枚派生常量 `UiKit.CAMP_HUD_BAND`(已实测:`Color(CAMP_HEADER_BAND, 0.80)` 编译通过,`to_html(true)`=`6e4526cc`,三分量与母 token 逐一相等),矩形由顶栏件自建。**甲淘汰**(引入一条零先例且无机器检查拦截的跨文件引用);**丙的"抽公共工厂"那一半不做**,理由与留痕句见第 12 节末。已落 T3.1、第 7 节结构图、第 12 节、契约4、第 13 节。**解释面报备**:轮次 2 复核指出裁决句字面只写「放在公共区域的这一层」,未逐字覆盖「矩形谁建」这条轴。写卡段按"该回话针对的是当轮给出的整条推荐(色值进公共件+矩形留在视图自建)"处置,故两半同批落卡;用户若不认这一读法,只需回一句,重开范围仅止于顶栏矩形的建造方,不动色值落点与其他结论。
> **裁决史(四次)**
> ① **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 用户裁乙·容器右对齐)**
@@ -318,13 +325,17 @@
写卡推荐=**乙**,理由=仓内已有同类摆位先例(容器 `alignment` 摆位,非手算偏移),且 R5 的 x 向判据在容器形态下读数最直白。甲依赖我不肯凭记忆断言的引擎语义(AGENTS.md:不确定的 API 一律核实后再用,核实前不作推荐)、丙新增运行期路径。
> **裁决(2026-11-05 用户裁·乙 容器右对齐)**:已落 T3.2 与第 12 节,Q2 清零。
> **裁决(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` 四处全部原样不动。
### 其余复核发现的处置(已落卡,非待裁)
自判与补写两类共 15 条已按复核者自己落卡的规矩改进行内:契约1 收窄措辞、`_start_adventure()` 函数体行号订正、失败分支终态申报、帧口径、R6 输入来源改读实件、R8 行号与能力行拆正、结构图验收行补 R7/R8、悬空「行为表」引用、L1 引用行号、白名单第 4 条取样口径、`_initialize()` 入口名、新件三查对 tests 不适用、完成定义行八行、`main.gd:137` 与其余开层点不受契约1 约束的明示。(轮次 1 对 R3 给的「升成员供测试直取」处置已在轮次 2 撤回——它抵触 `architecture.md:168` 视图单元接口与 `:323` 禁直引呈现层实现内部,改判为公开子节点序判据。)
自判与补写两类已按复核者自己落卡的规矩改进行内:契约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`)。两条都在待办清单在册(改动面=工具代码/状态=待执行),本批不动闸件。
@@ -338,44 +349,90 @@
| 轮次 | 复核者身份 | 发现(一句话) | 去向 | 处置结果 |
|---|---|---|---|---|
| 1 | 只读子代理·未参与撰写 | 契约1「隐藏点只许两处」按字面过宽——全库开始层显隐共 12 处 | 退回上游(复核者判)→ 落卡改自判 | 契约1 收窄为「限开局/续玩两条路径」,12 处逐条列名(`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`)。复核者的「退回上游」定名不采纳:这是卡内条款措辞过宽,非规范冲突,写卡段可自改 |
| 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「逐位相等」写不出来 | 补写(阻塞) | T2.1 同批把 `btn_row` 升为成员 `_btn_row`;R3 绑定面按 test-conventions §8.2 受控例外申报理由 |
| 1 | 同上 | §12 自称「不直取私有」,R3/R4 实际直取私有成员 | 自判 | §12 该格与 R3 改为受控例外口径(位次无公开可观测面可钉),不再谎称未直取 |
| 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 | 同上 | `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.2 改「待 Q2 裁决后落」;R5 已补 x 向判据(`end.x == 栏 end.x − 12`) |
| 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)」 |
| 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 待裁——**本卡现为「待裁未清零」状态,不进实现段、不落 commit、状态不推「已写卡」**。另其归入的机检缺口(`pipeline_gate.py:68` `ANCHOR_RE` 不含中文段)已列 §6 末行,去向=用户发令登记 |
| 1 | 同上 | 总判:按现状不能进实现段,缺四块闭合 | 退回上游(部分) | 四块里①②④已自决落卡;③的 `UiAssembler` 形态与 12px 机制转 Q1/Q2 待裁。另其归入的机检缺口(`pipeline_gate.py:68` `ANCHOR_RE` 不含中文段)已列 §6 末行,去向=用户发令登记 |
**写卡段对复核结论的两处不采信**(复核者也是读代码,不是跑批):`:679` 段头注的定性、五 token 机检「查无该件」——两处均经我逐行回读推翻,依据写在对应处置格。
**复核报告落盘**:`reports/复核-营地交互修复批-2026-11-05.md`(轮次 1=22 条,轮次 2=5 条,同一文件续段登记)。
**复核报告落盘**:`reports/复核-营地交互修复批-2026-11-05.md`(轮次 1=22 条,轮次 2=5 条,轮次 3=8 条,同一文件续段登记)。
## 轮次 2(Q1/Q2 裁决落卡后的独立复核)
## 轮次 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:51` |
| 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 原属甲/乙案内容 | 待裁(复核者判)→ **按自判落并报备** | 依据对话原话序列:写卡段呈案时那句推荐是「色值进公共件、矩形留在顶栏件自建」(两半同批给出),用户回话为「那没有问题,就按放在公共区域的这一层的方案来实现」——回话指向的是该推荐整体而非仅色值半轴,故按已裁处置。该解释已写入第 15 节 Q1 裁决格供比对;**用户若不认这个解释,本条重开为待裁**,且重开只影响顶栏矩形的建造方,不动其余结论 |
| 2 | 同上 | Q1 的裁决句「按放在公共区域的这一层」字面只覆盖色值落点;「矩形由顶栏件自建、不抽公共工厂」是写卡段对裁决的展开,该轴轮次 1 原属甲/乙案内容 | **待裁(复核者判,事后证明它判对)** | 写卡段当时把去向改成"自判+报备"并自行闭合——**该改判无效**:规矩是待裁必须问用户、禁代裁。11-06 用户驳回拆两半的方案,落点见第 15 节 Q1 裁决史②与④;本行处置因此从"已闭合"改记为"越权闭合→已由用户重裁" |
**轮次 2 总判**:三处补写已全部落卡;一处确认留档;一处按自判落并向用户报备(可重开)。落卡后本卡零待裁点。
**轮次 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(用户批卡)。**