docs(迭代33 三卡补验收闭合缺口): 按 test-conventions §9.8 旧卡开工前补表口径,为卡①②③各写改动—验收对照表(六列逐需求点,尾缀族 sv/mn/sl 可 grep;每行钉真实入口与撤销或变异证明)+测试削弱申报(卡② 废止断言族逐条写承接去向,卡③ ConfirmDialog 四点只许收紧)+独立验收审计声明与合并前置

三卡同批补 req-card 必备结构第 12 项「落位与可复用性预检」:卡① 盘上普查证实存档路径派生无第二处、slot 词已被同调位占用故新 API 取 save_slot_* 词族;卡② 零新增文件,开层函数复用 _open_career 与模态栈单口先例;卡③ 新视图只复制 CareerOverlay 页壳形制与 UiKit 工厂件,数据由组合根喂入、视图零文件 IO

顺带清卡③ 对已失效卡④裁断的依赖:契约 3 本批形态钉在双钮签名+消费方状态量编排(§9 第 6 条代拍板留痕),T0 禁与 v2.3 非有效卡对签名;三卡 §5 的 06/07 旧路径改指仓库根现行登记处与体验验证清单

文档域闸全绿(无新增红),回执 commit=c232e56e
This commit is contained in:
DKChan committed 2026-10-21 22:32:31 +08:00
1 parent c232e56ecf
commit 7705cf77ef
3 files changed
+147 -15

No files matched your search

@@ -1,6 +1,6 @@
# 需求卡片:主菜单三入口化批(6 钮 → 3 钮)· 营地交互重做卡②
- 版本:**v1.2**(2026-10-18 grilling 轮次回写——§0 补卡④回设计段注记(契约 5 中间态延长为工程批交付后稳态);本卡零待裁点不变,无其他裁定事项)
- 版本:**v1.3**(现行身份:零待裁点+含 §7.1 改动—验收对照表〔按 test-conventions §9.3 六列与 §9.8 旧卡开工前补表口径〕+§7.2 测试削弱申报。既有定性:契约 5 中间态因卡④回设计段延长为工程批交付后的稳态)
- 来源:[需求澄清-营地交互重做-2026-10-18.md](需求澄清-营地交互重做-2026-10-18.md)(唯一事实源:④结构树「主菜单(需改动:6 钮 → 3 钮)」、⑤裁决 1、②反参照、⑦切批原则②)
- 归属:呈现层/组合根(`game/presentation/`)——营地交互重做五卡之二
- 排期:未编入(2026-10-18 用户令:需求卡片不预占迭代号,批次归属按工作量另裁)
@@ -46,7 +46,7 @@
| F10 | **探针/单测/闸机影响面全量清单(v1.1 重列——初查「五探针」严重不全)**:见下表 | 全仓 grep 实证 |
| F11 | menu golden 基线在役:`game/tests/golden/menu_boot.png`(迭代 28 新增);对比段=render_gate.sh「菜单 golden 逐像素」节;重制入口=`tools/golden_baseline_refresh.sh --menu`(该脚本守卫素材齐盘,缺位拒跑) | `game/tests/golden/` 实查;`tools/render_gate.sh`(菜单 golden 节);`tools/golden_baseline_refresh.sh` 头注 |
| F12 | art-bible §7.4 小字号豁免为**一条合并条款**(条带内读数+装饰 caption 两类,:433),主菜单分组 overline×2(「── 冒 险 ──」「── 营地与系统 ──」)只是枚举中两个片段——禁整行删,只能 excision 片段;注销以 §9 第 1 条裁定为条件。另有两处代码注释引述组帽名(main.gd:287、career_overlay.gd:3,实施本体内可自理) | `design/art/art-bible.md:433`;`main.gd:287`;`career_overlay.gd:3` |
| F13 | 07-体验验证清单有两处引述主菜单形态(:170「左操作列(冒险/营地与系统两组)」、:192「营地与系统组出现生涯钮」)——随本批入口拓扑改 | `design/gdd/07-体验验证清单.md:170`/:192 |
| F13 | 体验验证清单有两处引述主菜单形态(:170「左操作列(冒险/营地与系统两组)」、:192「营地与系统组出现生涯钮」)——随本批入口拓扑改 | `体验验证清单.md:170`(仓库根)/:192 |
### F10 全量影响位点表(20+ 位点,按闸归类)
@@ -113,9 +113,9 @@
| `design/gdd/systems/跨局循环/生涯.md` | :9 信息架构「现行主菜单按钮组……『冒险』组……『营地与系统』组」+:11-23 结构树——六钮组记述整体失义;生涯入口从开始层迁营地笔记本 | 反哺点 · 信息架构节改三钮组+生涯入口位改挂 |
| `design/gdd/ux/camp.md` | :10「主菜单营地独立入口进入」——营地入口改挂存档内场景图 | 反哺点 · 定位句改挂 |
| `design/gdd/08-Alpha版本标准.md` | :102-105 三·界面表四行——状态列可改;入口拓扑注记列反哺点 | 反哺点 · 列清单(统一口径见上) |
| `design/gdd/07-体验验证清单.md` | :170/:192 两处引述主菜单形态(左操作列两组/营地与系统组生涯钮) | 反哺点 · 列清单(v1.1 补列) |
| `体验验证清单.md`(仓库根) | :170/:192 两处引述主菜单形态(左操作列两组/营地与系统组生涯钮) | 反哺点 · 列清单(该件属设计文档,实现批禁写) |
| `design/art/art-bible.md` | :433 小字号豁免合并条款中「主菜单分组 overline×2」枚举片段——组帽撤后 excision(禁整行删),以 §9 第 1 条裁定为条件 | 反哺点 · 列清单 |
| `design/gdd/06-待办清单.md` | 本卡登记条 | 反哺点 · 列清单 |
| `待办清单.md`(仓库根,流水线唯一登记处) | 本卡登记条 | 反哺点 · 列清单 |
| `roadmap.md` | 迭代行编入/状态刷新 | 反哺点 · 列清单 |
| `game/presentation/ui_assembler.gd`、`scenes/menu_screen.gd`、`main.gd`、`camp_shop_presenter.gd`(v1.1 补)、`game/smoke/*`、`game/tests/golden/*`、`tools/golden_baseline_refresh.sh`(重制入口,只跑不改) | 实现与断言/基线本体 | 实施本体(可写) |
@@ -123,6 +123,19 @@
> 估时按 Claude 工作日口径;每卡出口自跑轻闸;开工日 T0 复核全部行号。
### 6.0 落位与可复用性预检(req-card 必备结构第 12 项,定义 T 卡前置)
本卡零新增文件——改的全是既有承载面。逐件核查:
| 新增件/改动 | 复用面(既有实现) | 落点唯一性 | 分层与跨层出口 |
|---|---|---|---|
| 三钮钮集(改 `ui_assembler.gd:128-153`) | 钮全用 `UiKit` 工厂件(现役即 `primary_button`/`button`/`verb_button`),零新素材零新色值 | 主菜单钮集唯一构建口=`build_start_overlay`,盘上无第二处构建菜单钮的实现 | 装配层只产树与句柄,不持业务态 |
| 「进入存档」句柄(改 `scenes/menu_screen.gd:9-16`/`:27-31`) | 沿用屏壳句柄暴露形态(六句柄现制),只换钮名不改形态 | 屏壳句柄唯一暴露口=menu_screen,禁在装配层与组合根各存一份 | 屏壳→组合根只经 `pressed` 信号 |
| 组合根开层函数(新增 `_open_save_select`) | **复用同层先例 `_open_career`(`main.gd:1092-1095`:取数+开层+喂视图)**+模态栈单口 `_open_modal`/`_close_modal`(`:458-462`)+层序合同 `LAYER_CONTRACT`(`:34-53`,career 行见 `:47`) | 开层函数唯一在组合根,禁在屏壳或视图内自开层 | 呈现层禁直连数据层,取数一律在组合根完成后传入视图 |
| 删除 `_refresh_resume_button` | 无(净删除) | 删除即清掉一处散落 helper——消费点 12 处全清单见 §2 F5 与 mn7,漏删=留下第二处刷新口 | — |
| menu golden 重采 | **复用既有重制入口 `tools/golden_baseline_refresh.sh --menu`(F11)与 `tools/render_gate.sh` 菜单 golden 段** | 禁新写采图脚本、禁在探针里复制比对逻辑(逐像素比对唯一落点=golden 段) | 代码域闸统一入口,卡内不列闸件名单 |
| 断言与探针位点改写 | 全部改写既有段(smoke 与 F10 表内既有探针) | 禁新建同职责探针文件——同一入口的可达性只在一处断言 | 测试执行两入口铁规 |
### T0 事实坐实(≈0.5–1d)
- 复核 §2 全部行号;按 F10 表尾清点口径全仓 grep,清点结果写成文(T0 产物);
@@ -145,7 +158,7 @@
### T3 产出物落位卡(≈0.5d,末卡)
三份 `reports/` 写齐(实现报告含 golden 重制呈报记录、变异记录表、「已知中间态」节〔契约 5〕/代拍板追认单/反哺点清单)。
三份 `reports/` 写齐(实现报告含 golden 重制呈报记录、变异记录表、「已知中间态」节〔契约 5〕、**实际改动—验收对照表**〔§7.1 需求侧表的执行对账,另加「结果」格,F10 位点逐段指到行号〕/代拍板追认单/反哺点清单)。**合并前置**:独立验收审计(§7.1 末段声明)完成且 `reports/iter33-验收审计-<完成日>.md` 逐行「通过」;§7.2 申报外的削弱由审计判红,未过不得合并。
**估时合计 ≈2.5–4d**(v1.1 上调:探针面从「五探针」扩到 20+ 位点,T2 清点后重估)。切分预案:T1 出口可切(砍钮先落、断言迁移后落)——但契约 5 硬依赖卡③,实际切分价值低,建议与卡③同批单跑。
@@ -166,6 +179,43 @@
**闸口径**:轻闸每卡出口自跑;批末重闸按改动域选档(本批碰 `game/` 代码/断言/golden → `--code`)全绿才合并;MC 零跑(零数值零行为)。
### 7.1 改动—验收对照表(test-conventions §9.3 六列;§7 的 V 号在各需求点格内括注)
> 断言尾缀族=〔mn#〕,实现期逐条 grep 定位。落点文件为计划落点,实现期在 `reports/iter33-实现报告-<完成日>.md` 的实际对照表里按真实行号对账(§9.3 双端对上)。本卡是断言迁移卡,F10 全量位点表的每一段都必须能指到本表某一行——指不到的在实现报告标「由第 X 行覆盖」。
| 需求点 | 改动(文件:行/行为) | 验收测试(名称+落点+尾缀) | 层级 | 真实入口 | 撤销或变异证明 |
|---|---|---|---|---|---|
| mn1 三钮在位(契约1、V1、T1) | `game/presentation/ui_assembler.gd:128-153` `build_start_overlay` 六钮+两组帽 → 三钮(进入存档/设置/退出游戏) | 冒烟 V2 三钮非空段〔mn1〕落 `game/smoke/smoke_all.gd:163` 改写 | 接口 | 真实 `MenuScreen` 经 `UiAssembler.build_start_overlay()` 构建后读句柄 | 变异=把「生涯」钮接回三钮集 → 三钮断言红(T2 变异①) |
| mn2 四旧钮彻底撤出(契约1、V1、T1) | `game/presentation/scenes/menu_screen.gd:9-16`/`:27-31` 句柄面撤 `lvbtn`/`resumebtn`/`campbtn`/`careerbtn`、留 3+新增进入存档句柄 | 冒烟〔mn2〕四旧句柄名零命中+`ui_struct_probe` 结构断言 | 探针 | 菜单场景实例的句柄枚举(禁隐藏态、禁置灰态残留) | 撤销=恢复 `lvbtn` 字段 → 零命中断言红 |
| mn3 进入存档可达选档(契约3、V4、T1/T2) | `game/presentation/main.gd:307-309`/`:331-334` 接线区新增进入存档 → 开卡③选档层(开层函数名 T0 与卡③对齐) | `ui_click_probe` 新路径段〔mn3〕+`screen_flow_probe` 开合段 | 探针 | 合成点击进入存档钮 → 选档层可见且开始层隐藏 | 变异=接到营地层 → 层可见断言红(T2 变异②) |
| mn4 设置钮零行为变化(契约2、V2) | `settingsbtn` 接线保持不动(`main.gd:331-334`) | 冒烟 V3g settings 模态段复跑〔mn4〕 | 冒烟 | `settingsbtn` 句柄 `pressed` 驱动 | 撤销=断线 → V3g settings 段红 |
| mn5 退出接线正确(V3) | `quitbtn` → `_quit_game` 连接保持(`main.gd:331-334`) | 源码/结构断言〔mn5〕 | 单元 | `MenuScreen.quitbtn.pressed` 的连接目标名 | 变异=改连空函数 → 连接目标断言红 |
| mn6 断点确认主菜单零残留(契约4、V5、T1) | `main.gd:475-497` 摘除主菜单侧调用(弹窗本体与两分支逻辑落卡④大门) | 源码断言〔mn6〕+`ui_struct_probe` 既有 confirm 采样复跑 | 探针 | 主菜单路径上「开新冒险覆盖断点」确认链不可达 | 撤销=接线复现 → 残留断言红 |
| mn7 `_refresh_resume_button` 删除+消费点清零(T1、§9 第2条) | 函数删除(`main.gd:507-514`)+调用五处(`:194`/`:319`/`:704`/`:1063`/`:1101`)+`camp_shop_presenter.gd:19`/`:36`/`:55` ctx 字段与 `on_camp_closed` 调用+`probe_ui_util.gd:117-120` 参数+`pacing_queue_test.gd:30` | 单元〔mn7〕+表尾清点口径全仓 grep 零命中件核(T0 产物) | 集成 | 真实消费链:探针 `isolate_save()` 与营地关层回调 | 变异=漏删一处 ctx 字段 → grep 计数断言红 |
| mn8 废止断言族有改写承接(V1、T2) | `smoke_all.gd:266-290` V2d 续玩钮六断言、`:322`/`:326`+`:411-415` V3g campbtn 驱动营地开合、`:470-478`+`:565-567` V3i 阶段⑨续玩全链与 `_stage_faces.resume_vis` 键 | 改写后的三钮/新路径断言〔mn8〕逐族承接,同落点 | 冒烟 | boot 与回菜单生命周期段真实入口 | 撤销=只删不写承接 → 「每个废止族须有承接」计数断言红 |
| mn9 营地/生涯入口探针段改走新路径(V1、T2) | `ui_probe.gd:28-55`、`ui_click_probe.gd:59-127`、`ui_struct_probe.gd:41-45`/`:54-56`/`:69`、`screen_flow_probe.gd:53`/`:109-123` | 各探针自身绿+新路径断言〔mn9〕 | 探针 | 探针档默认跑各件,驱动路径=进档后开营地/生涯 | 撤销=入口段留旧句柄 → 取不到钮即 `_fail` 红 |
| mn10 冒险段探针直调中间态(契约5、V1、T2) | `_start_adventure_from_menu`/`_resume_from_menu` 保留函数仅摘接线;直调位点=`fx_shot_probe.gd:36-40`/`:47`、`t17_defer_probe.gd:29-33`、`ui_tune_probe.gd:96`、`ui_input_probe.gd:35`、`layout_probe.gd:27`、`smoke_all.gd:328`/`:439`/`:598`/`:628`、`screen_flow_probe.gd:130-136`、`shot_probe.gd:138-145`/`:193` | 各该段复跑绿〔mn10〕+实现报告「已知中间态」节逐位点登记 | 探针 | 函数直调(本行如实标为中间态入口,卡④到位后换代) | 撤销=删函数 → 直调段运行即红(红证明入口真落在该函数上) |
| mn11 组帽撤除+左列几何不破(V7、T1、§9 第1条) | `ui_assembler.gd:128`/`:141` 两枚 overline 与左列重排(「冒 险」帽必撤,「营地与系统」帽按 §9 处置并追认单留痕) | `ui_struct_probe` `_start_columns_contract`+`_audit("start")` 段复跑〔mn11〕 | 探针 | 真实菜单构建后的按钮几何审计(互压/等宽/出屏/零尺寸) | 变异=左列改单列致两列相交 → 不相交合同断言红 |
| mn12 menu golden 重制(V6、T2、契约6) | `game/tests/golden/menu_boot.png` 重采,走 `tools/golden_baseline_refresh.sh --menu`(脚本只跑不改) | `render_gate.sh` 菜单 golden 逐像素段〔mn12〕 | 探针/golden | render_gate 驱动 shot_probe 真机渲染出图逐像素比对 | 撤销=拿旧基线跑 → 钮集区差红;差区越出钮集区=触契约7 越界,路由 §8 L3 |
| mn13 `pacing_queue_test` 套件连带改造(V1、T1) | `game/tests/unit/presentation/pacing_queue_test.gd:30`/`:33` 去掉 `_refresh_resume_button` 与菜单直调依赖 | 该套件自身绿〔mn13〕 | 单元 | `game/tests/run_all.gd` 真实套件入口 | 变异=改成裸调下层队列函数 → 该套件的宿主链断言红(证明入口未绕过改动点) |
| mn14 反哺点清单(V8)——非行为改动 | §5 所列(生涯.md、camp.md、08、体验验证清单、art-bible `:433` excision、待办清单、roadmap)随批列点不落文 | 件核对表〔mn14〕落 `reports/iter33-反哺点-<完成日>.md` | 件核 | 收口前逐条指认落点 | 判断依据=产出物件核不产码;§5 任一条缺落点即 T3 收口不过 |
### 7.2 测试削弱申报(test-conventions §9.5)
本批结构性拆入口,必然动到既有断言——下列为**已申报**的改/删项,逐条写明判据去向,实现期未申报的削弱由独立验收审计判红:
| 旧断言位点 | 处置 | 承接判据 |
|---|---|---|
| `smoke_all.gd:266-290` V2d 续玩钮六断言 | 钮已撤,判据失去对象——废止 | 由〔mn8〕三钮/新路径承接断言顶上;卡① sv2 boot 态断言另钉「boot 后无激活态」 |
| `smoke_all.gd:322`/`:326`/`:411-415` V3g campbtn 直呼驱动 | 驱动路径换代 | 〔mn8〕+〔mn9〕新路径段(营地经进档开层) |
| `smoke_all.gd:470-478`/`:565-567` V3i 阶段⑨与 `_stage_faces.resume_vis` 键 | 键随钮退役 | 〔mn8〕承接改写;生命周期其余阶段断言不许动 |
| `ui_click_probe.gd:224-228`/`:462-518` 断点段(约 80 行) | 随弹窗移交卡④大门 | 本卡 T2 明列移交项+卡④重立卡时的接收清单两头登记;禁静默删除 |
| `shot_probe.gd:103-119`/`:126-133` career/camp 截图段 | 归卡④ | 七屏链存在性自检不许降档——V6 判据仍要求七件非空,缺件即红 |
| `ui_struct_probe.gd:86`/`:163-183` resume 专项 | 随钮改写 | 〔mn2〕〔mn8〕 |
| 冒险段探针的入口路径断言 | 降级为函数直调中间态 | 〔mn10〕逐位点登记在实现报告「已知中间态」节,卡④到位后代换——契约 5 明禁为凑绿把断言改成假路径 |
**独立验收审计(test-conventions §9.7)**:合并前由未参与实现的迭代 loop 内子代理(或用户点名会话)审计——只读本卡、实现报告实际对照表、diff 与测试文件,自跑最窄测试抽查,不采信「已全绿」;审计报告落 `reports/iter33-验收审计-<完成日>.md`,逐行写「通过/缺漏/例外及依据」。**审计未通过不得合并**(T3 合并前置)。
## 8. 异常分级
- **L1(自救)**:断言写法、探针路径选择、布局微调。
@@ -1,6 +1,6 @@
# 需求卡片:存档制数据层改造批(隐式单档 → 3 存档位)· 营地交互重做卡①
- 版本:**v1.2**(2026-10-18 grilling 轮次裁定回写——Q1 旧档归属裁定甲〔迁 1 号位,代拍板留痕〕、Q2 交付序列裁定甲〔推荐案,用户令按推荐执行〕;卡④回设计段不影响本卡链路——卡③在工程批内;v1.1 审查回写内容见文末审查回写要点)
- 版本:**v1.3**(现行身份:零待裁点+含 §7.1 改动—验收对照表〔按 test-conventions §9.3 六列与 §9.8 旧卡开工前补表口径〕。v1.2 裁定:Q1 旧档归属甲〔迁 1 号位,代拍板留痕〕、Q2 交付序列甲〔推荐案,用户令按推荐执行〕;卡④回设计段不影响本卡链路——卡③在工程批内)
- 来源:[需求澄清-营地交互重做-2026-10-18.md](需求澄清-营地交互重做-2026-10-18.md)(唯一事实源:④结构树「选档界面:3 存档位,新档/进档/删档」、⑤裁决 2/3/4、⑦切批原则①)+ [存档序列化](../design/gdd/systems/表现与支撑/存档序列化.md) P2 后置条
- 归属:数据层承载面(`game/core/save_manager.gd`)——营地交互重做五卡之一;用户可见面由卡③(选档界面)承载
- 排期:未编入(2026-10-18 用户令:需求卡片不预占迭代号,批次归属按工作量另裁)
@@ -82,7 +82,7 @@
| 文档 | 关联点(本批实现会改变它的哪条陈述) | 同步义务 |
|---|---|---|
| `design/gdd/systems/表现与支撑/存档序列化.md` | :61「存档是单文件 JSON(user://save.json)」→ 三槽承载;:20/:16 系统范围「单档 JSON 存档」;:165 P2 后置「多存档槽位|单档 MVP……多档等有真实需求再立项」——本批即该真实需求 | 反哺点 · 单文件→三槽口径改写+P2 条注销(去向=本批) |
| `design/gdd/06-待办清单.md` | 本卡登记条(卡片名/文件指针/状态) | 反哺点 · 列清单 |
| `待办清单.md`(仓库根,流水线唯一登记处) | 本卡登记条(卡片名/文件指针/状态) | 反哺点 · 列清单 |
| `roadmap.md` | 迭代行编入笔与批内状态刷新 | 反哺点 · 列清单 |
| `game/core/save_manager.gd`、`game/core/meta_progression.gd` | 承载面改造本体 | 实施本体(可写) |
| `game/smoke/*`、`game/tests/*` | 断言与隔离面 | 实施本体(可写) |
@@ -91,6 +91,21 @@
> 估时按 Claude 工作日口径;每卡出口自跑轻闸;开工日 T0 复核本卡全部行号。
### 6.0 落位与可复用性预检(req-card 必备结构第 12 项,定义 T 卡前置)
盘上普查(2026-10-21 实查,开工日 T0 复核):`user://save` 全仓命中 12 处——`save_manager.gd:15`/`:21` 是默认路径与注释,其余十处全是探针隔离纪律注释(`probe_ui_util.gd:89`、`screen_flow_probe.gd:23`、`smoke_all.gd:272`/`:588`/`:5696`/`:6539`、`ui_click_probe.gd:53`、`ui_input_probe.gd:30`、`ui_probe.gd:24`、`verifier_batch.gd:19`),**盘上不存在第二处存档路径派生**;`slot` 词已被同调位占用(`attunement.gd:10 static func slots(db, save)`、`config_db.gd:273`、`treasure_items.gd:56-57`)。
| 新增件 | 复用面(既有实现) | 为什么不能整件复用 | 唯一落点 | 跨层出口 |
|---|---|---|---|---|
| 三槽路径派生与槽位枚举 | 无同类实现可复用(普查见上,现承载面只有单 `_path`) | 新内容本身 | 只落 `save_manager.gd:15`/`:21` 承载面一处;探针面禁各自拼槽文件名,仍走注入口 | Core 层零 UI,禁 preload 玩法脚本(类头注 `:1-5`) |
| 激活位的设置/读取/清除 | `attach_path()`(`:42-46`)的「换路径+回默认数据+重读、对象引用恒定」正是切槽要复用的动作 | 该函数不带「哪一位被激活」的状态语义,需在其上加状态量而非另写一套换盘逻辑 | 激活态唯一在 SaveManagerCore 内存态;Q1 甲=不落盘,禁在 `meta_progression.gd` 或呈现层另记第二份 | 消费面经 `MetaProgression.save` 动态分发(`meta_progression.gd:21-25`/`:54`),禁回写引用(契约 6) |
| 新档/进档/删档三原语 | 读盘迁移链 `load_from_disk`(`:150-183`)、原子写 `write_to_disk`(`:188-202`)、坏档兜底 `_corrupt_fallback`(`:443-450`)、空态 `_default_data`——三原语=按槽复用这些件 | 现件全部单路径语义,需按槽参数化,不是重写 | 文件删除只落承载面,呈现层禁 `DirAccess` 直删 | 玩家侧二次确认弹窗归卡③,本卡只出原语 |
| 摘要三项按槽窥视读器 | 读源访问器在役:`keystone_balance()`(`:214`)、`adventure_total()`(`:258`)、`adventure_cleared()`(`:264`) | 现访问器读内存 `_data`(即激活态),窥视要按槽直读文件且零副作用(契约 9) | 三项口径唯一在本卡;卡③ 视图禁自算或加第四项(契约 5) | 只返回结构体,不带 UI 语义 |
| 三个新单元套件(`game/tests/unit/core/save_slot_*_test.gd`) | 既有 `test_kit.gd` 断言出口与 `unit/core/` 12 套件分层;存档往返先例 `game/tests/integration/save_rng_roundtrip_test.gd` | 既有件只证单实例单路径,位间隔离/启动态/跨槽摘要无对应件 | 一职责一文件、落 `unit/core` 与既有分层一致;禁把断言散写进 `smoke_all.gd`(该文件拆分在册=待办清单工程债第 6 条) | `game/tests/run_all.gd` 真实入口 |
| 承载面文件本体不拆 | `save_manager.gd` 现 481 行,本批改动集中于同一承载面 | — | 判据=req-card「库内大文件不擅自拆」;拆分归工程债批 | — |
标识符纪律:本批新增 API 词族取 `save_slot_*`/`activate_*`/`peek_*`,**禁复用裸名 `slots`**(同调位已占,`attunement.gd:10`),命名细节仍属 §9 第 3 条代拍板域。
### T0 事实坐实与裁点执行(≈0.5–1d)
- 复核 §2 全部行号与读数,漂移即订正本卡;
@@ -124,7 +139,7 @@
### T4 产出物落位卡(≈0.5d,末卡——三份 `reports/` 文件写齐才算收口)
轻闸全绿后、合并前:`reports/iter<N>-实现报告-<完成日>.md`(各卡状态+变异验证记录表)/`reports/iter<N>-代拍板追认单-<完成日>.md`(§9 白名单内代拍项留痕)/`reports/iter<N>-反哺点-<完成日>.md`(§5 每条一落点)。
轻闸全绿后、合并前:`reports/iter<N>-实现报告-<完成日>.md`(各卡状态+变异验证记录表+**实际改动—验收对照表**〔§7.1 需求侧表的执行对账,另加「结果」格,test-conventions §9.3〕)/`reports/iter<N>-代拍板追认单-<完成日>.md`(§9 白名单内代拍项留痕)/`reports/iter<N>-反哺点-<完成日>.md`(§5 每条一落点)。**合并前置**:独立验收审计(§7.1 末段声明)完成且 `reports/iter<N>-验收审计-<完成日>.md` 逐行「通过」——未通过不得合并,缺漏项回炉对应 T 卡。
**估时合计 ≈4.5–5.5d**(v1.1 上调:隔离面全清单+启动态/窥视三态断言增量)。切分预案:T1/T2 后可切(承载层先落、操作原语后落)——但本卡零用户可见面,切分价值低,建议单批跑完。
@@ -146,6 +161,31 @@
**闸口径**:轻闸每任务卡出口自跑;批末重闸 = `tools/run_all_gates.sh` 按改动域选档(本批只碰 `game/` 代码与断言面 → `--code`)全绿才合并;MC 零跑(零数值零行为——纯承载改造,同板同序列结算逐位一致由既有 parity 面承接)。
### 7.1 改动—验收对照表(test-conventions §9.3 六列;§7 的 V 号在各需求点格内括注)
> 断言尾缀族=〔sv#〕,实现期逐条 grep 定位。落点文件为计划落点,实现期在 `reports/iter33-实现报告-<完成日>.md` 的实际对照表里按真实行号对账(§9.3 双端对上:正向每需求点一行、反向每行为改动一行、测试侧每条新断言挂一行)。层级取值见 §9.2 四层。
| 需求点 | 改动(文件:行/行为) | 验收测试(名称+落点+尾缀) | 层级 | 真实入口 | 撤销或变异证明 |
|---|---|---|---|---|---|
| sv1 三槽承载+位间隔离(契约1/2、V1、T1) | `game/core/save_manager.gd:15` `var _path` 单路径 → 三槽路径派生+当前激活位字段(机制取 §9 第 1 条) | 冒烟 `save_slot_roundtrip`〔sv1〕落 `game/smoke/smoke_all.gd` + 单元 `game/tests/unit/core/save_slot_isolation_test.gd`〔sv1〕 | 接口 | `SaveManagerCore` 实例的按槽 API 读写往返,不经 UI | 变异=三槽路径派生写成同一文件 → 三槽往返一致断言红(T3 变异①) |
| sv2 启动态不读盘(完成定义3、V1、T1) | `save_manager.gd:21` `_init` 默认参 `"user://save.json"` 取消+初态 `_data`=`_default_data` | 单元 `game/tests/unit/core/save_boot_no_activate_test.gd` boot 三断言〔sv2〕 | 单元 | 组合根 boot 链起的 `/root/SaveManager`(`game/project.godot:21` autoload 序) | 变异=`_ready` 内偷调 `load_from_disk` → boot 断言红(T3 变异④) |
| sv3 无激活态写盘一律拒绝并返回 false(契约6、V1、T1/T2) | `save_manager.gd:188-202` `write_to_disk` 入口加激活态判定 | 单元〔sv3〕「拒写+返 false+盘面无新文件」三断言,同上落点 | 接口 | `MetaProgression.settle_adventure()`(`meta_progression.gd:284`)无激活态触达写盘 | 撤销=去掉判定放行旧入口 → 拒写断言红 |
| sv4 新档原语(完成定义2、V2、T2) | 新增空槽创建,初值取 `_default_data` 全零可玩纪律 | 冒烟段〔sv4〕落 `smoke_all.gd` 新档子段 | 接口 | 空槽调新档 API 后按域读回 | 变异=新档写成读旧档 → 全零可玩断言红 |
| sv5 进档原语(V3、T2) | 进档=激活+读盘,复用 `load_from_disk`(`save_manager.gd:150-183`)按槽成立 | 冒烟段〔sv5〕 | 接口 | 槽 N 有档 → 进档 API → 读回=该槽档案内容 | 变异=进档只置激活指针不读盘 → 读回断言红 |
| sv6 删档原语(契约8、V4、T2) | 新增删除:文件删除+该槽回合法空态+激活指针连清除+无 `.tmp` 残留 | 冒烟段〔sv6〕含文件系统存在性断言 | 集成 | 激活槽调删档 API,再经访问器读该槽+盘面核查 | 变异=漏删文件 → 在盘断言红(T3 变异②) |
| sv7 摘要三项按槽窥视(契约5、V5、T2) | 新增按槽窥视读器,读源=`keystone_balance()`/`adventure_cleared()`/`adventure_total()`(`save_manager.gd:214`/`:264`/`:258`) | 单元 `game/tests/unit/core/save_slot_summary_test.gd`〔sv7〕三槽异值+空槽零值 | 单元 | 窥视 API 按槽调用(不激活不写盘) | 变异=摘要读激活位代替窥视位 → 跨槽摘要红(T3 变异③) |
| sv8 窥视三态零副作用(契约9、V5、T2) | 窥视对损坏/高版本槽返回显式损坏标记,禁触发 `_corrupt_fallback`(`:443-450`)改名 | 冒烟段〔sv8〕窥视前后文件字节与 mtime 双比对 | 接口 | 盘上坏槽夹具 → 窥视 API | 变异=窥视改走正式 load 路径 → 字节/mtime 断言红 |
| sv9 迁移链各槽成立(契约3、V6、T1/T3) | v1→v7 六件迁移链(`:25-30` 自注册)不动,执行面按槽独立成立 | 冒烟段〔sv9〕三槽各喂旧版本档→各读回相等 | 接口 | 各槽 `load_from_disk` | 变异=迁移只跑激活槽 → 他槽读回断言红 |
| sv10 切槽=同实例整体换 `_data` 与路径(契约6、V1、T1) | 激活切换取 `attach_path` 先例(`:42-46`);`MetaProgression.save` 引用(`meta_progression.gd:21-25`/`:54`)禁换实例 | 单元〔sv10〕切槽前后引用同一性+写盘落当前槽 | 集成 | `MetaProgression` 真实宿主链驱动切槽 | 变异=切槽新建实例 → 同一性断言红;写成落错槽 → 位间隔离断言红(T3 变异⑤) |
| sv11 测试隔离面保留(契约7、V7、T0/T3) | `attach_path` 与注入路径语义钉为「注入=激活槽文件,无激活态时注入即激活并重读」——`smoke_all.gd:5701-5708` 18 条、`:6499-6511` 15 条、`probe_ui_util.gd:98-121` tag 族行为零变化 | 既有冒烟/探针段全数复跑〔sv11〕+T0 隔离面清点成文件核 | 集成 | 各探针 `isolate_save()` 与 `attach_path` 现有调用面 | 撤销=注入路径改成忽略 → 依赖隔离的既有断言成片红(成片红即本行证明) |
| sv12 旧档处置 Q1 甲(契约4、V8、T0) | 首次启动把 `user://save.json` 原样迁入槽 1;幂等=槽 1 已存在不重迁;旧档处置按 §10 Q1「执行前置检查」列逐项 | 冒烟段〔sv12〕迁移前后逐域相等+槽 2/3 空+处置字节留痕件核 | 接口 | 盘上放旧档夹具跑启动链迁移 | 变异=去掉幂等判据 → 二次启动重复迁移断言红;损坏+高版本叠加等意外形态路由 §8 L3 呈报 |
| sv13 不升 schema 版本(契约3、完成定义4)——非行为改动 | `SAVE_FORMAT_VERSION := 7`(`:9`)与 `_normalize`(`:458-471`)零改动;确需新键按「v6 域后扩列不升版」先例登记 | 既有版本与高版本拒读断言复跑〔sv13〕 | 单元 | 既有冒烟版本段 | 判断依据=本行不改任何行为;撤销它=升版即撞既有高版本拒读断言(该断言已由 sv9 面钉住) |
| sv14 反哺点清单(V9)——非行为改动 | §5 所列文档陈述(存档序列化.md `:61`/`:20`/`:165` 等)随实现换代,本批只列点不落文 | 件核对表〔sv14〕落 `reports/iter33-反哺点-<完成日>.md` | 件核 | 收口前逐条指认落点 | 判断依据=产出物件核不产码;§5 任一条缺落点即 T4 收口不过 |
**测试削弱申报(test-conventions §9.5)**:本卡允许改写的既有断言=boot 链 V2d-1(续玩钮恒隐)——按 T3 明列处置改写为「boot 态续玩钮恒隐」或注明由卡② V2 改写承接,禁判据空转;sv11 清单内既有段只许复跑不许动。除本段申报,实现期任何删除断言、放宽阈值、缩小扫描面、换下层直调,由独立验收审计判红。
**独立验收审计(test-conventions §9.7)**:合并前由未参与实现的迭代 loop 内子代理(或用户点名会话)审计——只读本卡、实现报告实际对照表、diff 与测试文件,自跑最窄测试抽查,不采信「已全绿」;审计报告落 `reports/iter33-验收审计-<完成日>.md`,逐行写「通过/缺漏/例外及依据」。**审计未通过不得合并**(T4 合并前置)。
## 8. 异常分级
- **L1(自救)**:断言写法、命名、文件落点。
@@ -1,6 +1,6 @@
# 需求卡片:选档界面新建批(3 存档位 · 新档/进档/删档)· 营地交互重做卡③
- 版本:**v1.2**(2026-10-18 grilling 轮次裁定回写——Q1 裁定甲(每轮回选档,代拍板留痕)、Q2 裁定甲(坏槽按空槽,推荐案)、Q3 裁定乙(进档暂行接现役 CampOverlay——卡④同日回设计段迫使);契约 3 落 ConfirmDialog 三钮化定局(卡④ Q5 裁定甲);用户面裁决照录澄清文档不变)
- 版本:**v1.3**(现行身份:零待裁点+含 §7.1 改动—验收对照表〔按 test-conventions §9.3 六列与 §9.8 旧卡开工前补表口径〕+§7.2 测试削弱申报。裁定记录:Q1 甲〔每轮回选档;本项无推荐案,取默认甲代拍板留痕、追认单可 veto〕、Q2 甲〔坏槽按空槽,推荐案〕、Q3 乙〔进档暂行接现役 CampOverlay,卡④回设计段迫使〕;契约 3 的本批形态按 §9 第 6 条钉在双钮+消费方编排上;用户面裁决照录澄清文档不变)
- 来源:[需求澄清-营地交互重做-2026-10-18.md](需求澄清-营地交互重做-2026-10-18.md)(唯一事实源:④结构树「选档界面(完全没有 · 新建):3 存档位,新档/进档/删档」、⑤裁决 2/3/4、⑦切批原则③)
- 归属:呈现层/组合根(`game/presentation/`)——营地交互重做五卡之三
- 排期:未编入(2026-10-18 用户令:需求卡片不预占迭代号,批次归属按工作量另裁)
@@ -9,7 +9,7 @@
## 0. 前置依赖与并行性
- 前置卡①(存档制数据层改造批):三槽承载、新档/进档/删档原语、摘要三项窥视读器——本卡只做界面与接线,不碰数据层实现。
- 后接卡④(营地场景图):进档/新档的落点。**卡④已于 2026-10-18 回设计段(美术设计定稿未过 2026-10-10 设计前置闸——见卡④ 卡头回退声明)**,故 Q3 裁定乙:本卡随①②③工程批先行时,进档/新档**暂行接现役 CampOverlay**(现役在役面,复用合法,非「发明占位」),卡④设计定稿重新立卡后改挂场景图(卡④ T3 承载)。
- 后接卡④(营地场景图):进档/新档的落点。**卡④已于 2026-10-21 用户令退回美术设计段**(美术轨凭据缺 P1–P5 未销号,现卡 v2.3 非有效卡——见卡④ 卡头回退声明),故 Q3 裁定乙:本卡随①②③工程批先行时,进档/新档**暂行接现役 CampOverlay**(现役在役面,复用合法,非「发明占位」),卡④设计定稿重新立卡后改挂场景图(卡④ T3 承载)。
- 卡②(主菜单三入口化)的「进入存档」钮以本卡为落点,两卡硬耦合(卡② 契约 5:同批或卡③在先)。
- 卡⑤(ESC 浮窗)在本卡语境不响应(卡⑤ 契约 2:ESC 范围=营地语境)——选档语境的键盘行为零裁定、零实现。
@@ -46,7 +46,7 @@
🔴 **契约 2 · 摘要三项且仅三项**:钥石余额/通关次数(=通关局数 `adventure_cleared`)/冒险总局数(裁决 4)。**禁显示有无未完冒险**(用户原话「不需要显示有无未完成的冒险;只要我提到的那三个就够了」)——断点相关读数(关数/种子/停点)零露出。
🔴 **契约 3 · 删档必经二次确认+ConfirmDialog 消费方机制(v1.2 落定:类将三钮化)**:第一次点击只出确认窗(复用 ConfirmDialog 类),确认才删、取消不删;禁长按删、禁一次点击即删、禁撤销式软删。**该类现为双钮零 payload 单实例,将有三个消费方**(现役新冒险确认〔随卡②退役〕、卡③删档确认、卡④大门两分支确认)——组合根须实现「打开时指定消费方」机制(待确认消费方状态量:open 前设、confirmed/cancelled 后分派;或信号带用途载荷),**禁双常驻静态接线**(现役 main.gd:347 形态禁复制——双线必致删档确认误触发开局)。**三钮化已定局(2026-10-18 卡④ Q5 裁定甲)**:类将扩为「确认/取消/第三钮」形态(第三钮语义随卡④大门裁后落),本卡删档确认只用取消/确认两钮;类签名随卡④重新立卡时的实现落地,本卡 T0 对齐。
🔴 **契约 3 · 删档必经二次确认+ConfirmDialog 消费方编排机制**:第一次点击只出确认窗(复用 ConfirmDialog 类),确认才删、取消不删;禁长按删、禁一次点击即删、禁撤销式软删。**本批内该类的形态钉在现役双钮签名**(`confirm_dialog.gd:36-38` `open(text, confirm_label, cancel_label)`,信号零 payload 单实例)——三钮形态与第三钮语义属卡④(v2.3 非有效卡,Q5 裁定甲的落点在那张卡重立卡后的批),本批禁预支类签名变更。**编排机制取 §9 第 6 条代拍板**:组合根按「open 前设消费方状态量、confirmed/cancelled 后按该状态量分派」实现,**禁双常驻静态接线**(现役 `main.gd:347` 形态禁复制——双线必致删档确认误触发开局)。本批该类的消费方=卡③删档确认一处(现役新冒险确认入口随卡②撤出),但分派面禁写死单一目标,须让卡④到位后直接接入第三消费方而不返工。
🔴 **契约 4 · 空/有档操作集二分**:空槽只有「新档」;有档槽有「进档」+「删档」(澄清④语义)。**禁给空槽配删档**(含置灰残留——置灰=配删档);「想在这个位开新局」的玩家路径=先删档(二次确认)→槽回空→新档,两步即达,卡内记载备查(实现期禁自发加「覆盖」钮——覆盖式新档用户未裁);坏槽/高版本槽的操作集=Q2 裁定,不属本二分。
@@ -75,7 +75,7 @@
| 文档 | 关联点 | 同步义务 |
|---|---|---|
| `design/gdd/06-待办清单.md` | 本卡登记条;存档序列化 P2 多档条(卡①反哺)与本条的交叉注记 | 反哺点 · 列清单 |
| `待办清单.md`(仓库根,流水线唯一登记处) | 本卡登记条;存档序列化 P2 多档条(卡①反哺)与本条的交叉注记 | 反哺点 · 列清单 |
| `design/gdd/systems/跨局循环/生涯.md` | :11-23 信息架构结构树——新增「进入存档→选档界面」一级层级(生涯入口随卡④改挂笔记本) | 反哺点 · 结构树补层 |
| `design/gdd/08-Alpha版本标准.md` | 「三 · 界面」表新增「选档界面」行(在役)——增行须用户裁(08 头注纪律) | 反哺点 · 增行请求随清单呈报 |
| `roadmap.md` | 迭代行编入/状态刷新 | 反哺点 · 列清单 |
@@ -85,10 +85,24 @@
> 估时按 Claude 工作日口径;每卡出口自跑轻闸;开工日 T0 复核全部行号。
### 6.0 落位与可复用性预检(req-card 必备结构第 12 项,定义 T 卡前置)
本卡只有一个新增文件与一个新增开层函数,其余全部复用。盘上形制先例=生涯页 `CareerOverlay`(`game/presentation/views/career_overlay.gd` 全屏页壳+`open_career(data: Dictionary)` 收数据+`_emit_closed` 关闭;组合根四处登记面见 `main.gd:47` 层序合同行、`:116` 字段、`:288-290` 构造与接线、`:419` 层查找表、`:1092-1095` 开层函数)。
| 新增件 | 复用面(既有实现) | 为什么不能整件复用 | 唯一落点 | 分层与跨层出口 |
|---|---|---|---|---|
| 新文件 `game/presentation/views/save_select_overlay.gd`(`SaveSelectOverlay`) | 页壳工厂 `UiKit.page_shell`(`career_overlay.gd:18-31` 同款先例)、紧凑返回钮先例(`:26-31`)、关闭链 `signal closed`+`_emit_closed`(`:75-79`) | 生涯页是只读跨局汇总、零存档操作集——**复用它的页壳形制与工厂件,不复用它本体**(澄清④判选档面「完全没有·新建」) | 视图文件只落 `views/` 一处,禁把槽卡构建 helper 散进 `ui_assembler.gd` 或 `main.gd` | 视图零数据层依赖:槽摘要由组合根取好传入(照 `open_career(_career_data())` 先例),视图内禁出现 `load()`/`DirAccess`/存档路径 |
| 三槽卡与槽态判定 | 钥石徽工厂件 `UiKit.keystone_badge`(F4 三处消费先例) | 现无「按槽」呈现件 | 槽数量与槽态(空/有档/坏槽)唯一来处=卡① 窥视 API 返回值,视图禁自己数文件、禁硬编码三槽判定 | 呈现层→Core 只经卡① 类型化访问器(卡① 契约 6) |
| 开层函数(组合根) | 模态栈单口 `_open_modal`/`_close_modal`(`main.gd:458-462`)+`LAYER_CONTRACT` 登记(`:34-53`)+开始层互斥仿设置面先例 | 现无选档层可复用 | 新层只在 `LAYER_CONTRACT` 加一行(改层序只改合同表,散写 `move_child` 由冒烟 V1d 判红) | 开合走栈单口;ConfirmDialog 按契约 6 豁免沿用直开先例 |
| 删档确认弹窗 | 复用 `ConfirmDialog` 类(F2)+现役直开先例(`main.gd:480`) | 类本体够用,缺的是多消费方分派 | 消费方状态量唯一落点在组合根,禁在视图与弹窗各存一份 | 弹窗类零业务触碰(现役纪律),禁反向依赖玩法 |
| 探针与夹具 | 既有 `ui_struct_probe`/`ui_click_probe`/`screen_flow_probe` 各加段;隔离存档夹具 `probe_ui_util.gd:98-121 isolate_save` | 三槽异值夹具经卡① 槽位 API 直写(能力验证口径),禁在视图侧开调试口 | 同一入口的可达性断言只在一处,禁新建同职责探针文件 | 测试执行两入口铁规 |
零新增清单(契约 7 同源):不新增素材、不新增色值、不新增弹窗类、不新增存档路径派生、不新增槽位数量常量(位数唯一在卡① 承载面)。
### T0 事实坐实与接口对齐(≈0.5–1d)
- 复核 §2 行号;与卡①对齐窥视读器签名/命名/返回结构/空槽与坏槽表示法(卡① 契约 9 三态——对齐结论写成文附 §2,消 L3 落空项);
- 与卡②对齐「进入存档」钮句柄;与卡④对齐进档落点开层函数+**ConfirmDialog 消费方编排机制**(契约 3——卡④同款契约互指);
- 与卡②对齐「进入存档」钮句柄;进档/新档落点=现役 CampOverlay 的开层函数(Q3 乙),其签名与本卡激活调用在 T0 与卡①的激活 API 对齐;ConfirmDialog 消费方编排机制按契约 3+§9 第 6 条实现,卡④重立卡后按同一机制接入第三消费方(本批禁与卡④对接签名——卡④ v2.3 非有效卡)。
- 清点既有 confirm_dialog 断言面(ui_struct_probe.gd:71 结构采样、smoke_all.gd:226 最顶层候选、ui_click_probe:508-527、ui_tune_probe.gd:52 树序断言)——机制或实例数若变,这些点受影响;
- Q1 重启初始态与 Q2 坏档第三态裁定执行。
@@ -117,7 +131,7 @@
### T4 产出物落位卡(≈0.5d,末卡)
三份 `reports/` 写齐。
三份 `reports/` 写齐(实现报告含**实际改动—验收对照表**〔§7.1 需求侧表的执行对账,另加「结果」格〕、变异记录表、「已知中间态」节〔Q3 乙的暂行接线与卡④改挂的二次验证面〕/代拍板追认单〔含 §9 第 6 条编排机制留痕〕/反哺点清单)。**合并前置**:独立验收审计(§7.1 末段声明)完成且 `reports/iter33-验收审计-<完成日>.md` 逐行「通过」;§7.2 申报外的削弱由审计判红,未过不得合并。
**估时合计 ≈4.5–5.5d**(v1.1 上调:ConfirmDialog 机制+坏槽态+返回路径+夹具注入增量)。切分预案:T1/T2 后可切(视图先落、接线后落)——切分价值低,建议与卡②同批单跑。
@@ -141,11 +155,38 @@
**闸口径**:轻闸每卡出口自跑;批末重闸按改动域选档(本批碰 `game/` 代码与断言面 → `--code`)全绿才合并;MC 零跑。
### 7.1 改动—验收对照表(test-conventions §9.3 六列;§7 的 V 号在各需求点格内括注)
> 断言尾缀族=〔sl#〕,实现期逐条 grep 定位。落点文件为计划落点,实现期在 `reports/iter33-实现报告-<完成日>.md` 的实际对照表里按真实行号对账(§9.3 双端对上)。本卡全部取数只走卡① 交付的按槽 API,夹具按槽直写=能力验证口径(§7 两分法)。
| 需求点 | 改动(文件:行/行为) | 验收测试(名称+落点+尾缀) | 层级 | 真实入口 | 撤销或变异证明 |
|---|---|---|---|---|---|
| sl1 三槽呈现(契约1、V1、T1) | 新建 `game/presentation/views/save_select_overlay.gd`(`SaveSelectOverlay._init` 按 `career_overlay.gd:18-31` 页壳先例)渲染三槽卡 | `ui_struct_probe` 新段〔sl1〕槽卡计数=3+零滚动容器 | 探针 | 点「进入存档」开层后的真实子树 | 变异=槽列表参数化成四槽或套 ScrollContainer → 计数与禁滚动断言红 |
| sl2 摘要三项逐槽读数(契约2、V2、T1/T2) | 槽卡内容读卡① 按槽窥视 API(三值+零值空槽) | 探针段〔sl2〕夹具按槽直写三槽异值后逐槽断言 | 探针 | 开层后各槽卡 label 实取值 | 变异=摘要改读激活槽代替窥视槽 → 异值夹具下断言红 |
| sl3 摘要禁项(契约2、V3、T1) | 槽卡只消费三项键,零断点字段(关数/种子/停点不进视图) | 探针禁词断言〔sl3〕 | 探针 | 选档层真实 label 文本全集枚举 | 变异=把断点关数拼进槽卡副标题 → 禁词断言红 |
| sl4 空/有档操作集二分(契约4、V4、T1) | 槽卡按槽态分支渲染钮集;空槽禁渲染删档钮(含置灰形态) | 结构断言〔sl4〕空槽零删档钮+有档槽零新档钮 | 探针 | 真实开层子树的钮枚举 | 变异=空槽渲染删档钮(哪怕 `visible=false`)→ 操作集断言红 |
| sl5 空槽新档链(完成定义3、V5、T2) | 组合根新档回调:卡① 空槽创建→激活→暂行开现役 CampOverlay(Q3 乙) | `ui_click_probe` 合成点击段〔sl5〕 | 集成 | 真实点击空槽「新档」钮 | 撤销=去掉激活调用 → 激活槽位断言红 |
| sl6 有档槽进档链(契约8、V6、T2) | 组合根进档回调:卡① 激活→暂行开现役 CampOverlay | `ui_click_probe` 段〔sl6〕 | 集成 | 真实点击有档槽「进档」钮 | 变异=进档读成当前激活槽 → 该槽摘要与激活位断言红 |
| sl7 删档二次确认链(契约3、V7、T2) | 删档回调经 ConfirmDialog 编排:`main.gd:480` 直开先例+消费方状态量,confirmed 才调卡① 删除原语,cancelled 只关窗 | `ui_click_probe` 双路径段〔sl7〕(一击只开窗/取消后文件仍在/确认后删+槽回空) | 集成 | 真实点删档钮 → 确认窗 → 确认与取消两支 | 变异=删档钮直连删除原语 → 确认链断言红(T3 变异①) |
| sl8 消费方编排机制(契约3、V7、T2、§9 第6条) | `main.gd:347-348`/`:480` 静态常驻接线改为「open 前设消费方状态量、confirmed/cancelled 后按该量分派」,弹窗类签名不动 | 结构断言〔sl8〕单口分派+变异注入双常驻接线 | 集成 | 三个开窗路径共用同一弹窗实例(本批两个:删档确认与现役新冒险确认随卡②撤出) | 变异=保留双常驻静态接线 → 「删档确认误触发开局」断言红(T3 变异④) |
| sl9 重启不预选(Q1 甲、V8、T1/T2) | 视图与组合根零激活位持久化(卡① §9 第 2 条随 Q1 甲作废),boot 后三槽均未选 | 探针重启链段〔sl9〕 | 集成 | 重启后走「进入存档」开层 | 变异=加一条持久化预选指针 → 不预选断言红 |
| sl10 返回路径与 ESC 语境(V9、T1/T2) | 页壳返回钮 → `_close_modal`+开始层恢复(`career_overlay.gd:75-79` 先例);选档语境 ESC 不响应(卡⑤ 契约 2 范围外,零实现) | `screen_flow_probe` 型段〔sl10〕 | 探针 | 真实点击返回钮+选档态按 ESC 键 | 变异=返回钮改成 `queue_free` 不恢复开始层 → 恢复断言红;给 ESC 加处理 → 不响应断言红 |
| sl11 层序与模态纪律(契约6、V10、T1/T2) | 新层入 `main.gd:34-53` `LAYER_CONTRACT`(仿 `:47` career 行)+开合走 `:458-462` 模态栈单口 | 冒烟 V1d 合同断言〔sl11〕+`ui_tune_probe.gd:52` 树序断言复跑 | 冒烟 | `smoke_all.gd:146-154` 源码合同段 | 变异=在视图内散落 `move_child` → 散落判红 |
| sl12 动线序不回闪(T2) | 进档/新档时先落点开层(开始层保持隐藏)再关选档 | 探针段〔sl12〕逐帧可见性次序(选档隐藏时营地层已可见) | 探针 | 真实点击进档钮后的可见性采样 | 变异=改成先关后开 → 开始层恢复一帧断言红 |
| sl13 公共件复用零新素材零新色值(契约7、V1)——非行为改动 | 只用 `UiKit.page_shell`/`UiKit.keystone_badge`/现行色板;不新增素材与色值 | 静态扫描+结构断言〔sl13〕零新 `Color(` 字面量与素材路径 | 件核 | 本批 diff 文件枚举 | 判断依据=不改行为;变异=引入新色值 → 静态扫描红 |
| sl14 反哺点清单(V11)——非行为改动 | §5 所列(待办清单、生涯.md 结构树、08 增行请求、roadmap)列点不落文 | 件核对表〔sl14〕落 `reports/iter33-反哺点-<完成日>.md` | 件核 | 收口前逐条指认落点 | 判断依据=产出物件核不产码;08 增行须用户裁,本批禁直改 |
### 7.2 测试削弱申报(test-conventions §9.5)
本卡接线会让 ConfirmDialog 的开窗形态变化,下列四点为**已申报**的可改写位点(改写须按新形态收紧,禁放宽):`ui_struct_probe.gd:71` 结构采样、`smoke_all.gd:226` 最顶层候选、`ui_click_probe.gd:508-527` 确认弹窗交互段、`ui_tune_probe.gd:52` 树序断言。改写条件=实例数或分派口变化时同步更新判据;不许把判据放宽成「任意弹窗在顶」。其余既有断言本卡不许动,实现期未申报的删除断言、放宽阈值、缩小扫描面、换下层直调由独立验收审计判红。
**独立验收审计(test-conventions §9.7)**:合并前由未参与实现的迭代 loop 内子代理(或用户点名会话)审计——只读本卡、实现报告实际对照表、diff 与测试文件,自跑最窄测试抽查,不采信「已全绿」;审计报告落 `reports/iter33-验收审计-<完成日>.md`,逐行写「通过/缺漏/例外及依据」。**审计未通过不得合并**(T4 合并前置)。
## 8. 异常分级
- **L1(自救)**:断言写法、槽卡布局微调、命名。
- **L2(记录继续)**:槽卡横列/纵列布局取舍(契约 1 内)、确认文案措辞、空态呈现细节。
- **L3(停机呈报)**:进档落点在卡④重新立卡前被要求改挂场景图(Q3 裁定乙=暂行现役 CampOverlay,提前改挂=越批);卡① 交付签名与 T0 对齐结论不符(v1.1 订正原「与本节假设不符」——本节无签名假设);删档确认链被要求简化(触裁决 3);ConfirmDialog 消费方机制与卡④无法对齐。
- **L3(停机呈报)**:进档落点在卡④重新立卡前被要求改挂场景图(Q3 裁定乙=暂行现役 CampOverlay,提前改挂=越批);卡① 交付签名与 T0 对齐结论不符(v1.1 订正原「与本节假设不符」——本节无签名假设);删档确认链被要求简化(触裁决 3);ConfirmDialog 编排机制在本批内出现两个分派目标互相冲突(冲突时停机呈报,禁为实现方便退回双常驻静态接线)。
## 9. 代拍板白名单(超清单必呈报)
@@ -154,6 +195,7 @@
3. 新档/进档/删档三钮的文案与动词化命名(对齐现役动词钮先例)。
4. 选档界面与开始层的互斥方式(仿设置面先例内的参数选择)。
5. 提交切分与 worktree 分支命名。
6. ConfirmDialog 消费方编排机制的取法:**取「open 前设消费方状态量、confirmed/cancelled 后按该量分派」**(约束:不破现役双钮签名 `confirm_dialog.gd:36-38`,禁双常驻静态接线,分派面须可容纳卡④到位后的第三消费方)——代拍板留痕,追认单可 veto。
## 10. 待裁点