Merge branch 'master' into iter43

This commit is contained in:
DKChan committed 2026-10-29 23:35:12 +08:00
commit d7b8839fcf
38 files changed
+1328 -105

No files matched your search

@@ -0,0 +1,85 @@
# grilling 复核报告——零豁免五卡(2026-10-29,主会话委派)
状态行:对抗式复核完成。方法=逐卡过审点 A–J(验收三问/对照表两端/静态判据形态/能力行锚定/预算实数/拆分纪律/编队碰撞/行为改动完备性/裁决一致性/可施工性),判据=req-card 必备结构 15 节+code-conventions §1.1+test-conventions §8;证据=五卡 file:line 抽验约 90 处(命中率高,个别 1 行漂移属 T0 兜住范围)+五份设计文档口径核对+architecture v1.25+能力清单逐行核对+gdstyle_baseline.txt 键账清点+迭代 42 在飞两卡触面比对+pipeline_gate 全绿。只读复核,未改任何卡与既有文件。
## 卡一:gdstyle 尾波补件批(board_hover+breakpoint_store)
**裁决:有条件成立**(四项编入前须补,均为编辑级补丁,不动拆件方案本身)。
逐条发现:
1. 【应修】卡面 §7 编队注记——「与呈现层状态件批同代时**推荐**其先行」,而呈现层状态件批 §3 已把同一约束写死为「已裁……本批先于其 board_hover 半边合回」的硬义务。同一约束两卡一软一硬,编排段按弱措辞排卡会让 hover 拆件落在旧 u.st 写入面上、board_view 改址对账表(单格篇 §5.1)随之失配。改法:board_hover 半边改成硬前置句「呈现层状态件批合回后施工」;breakpoint_store 半边明示不受此限、可独立先行。
2. 【应修】§8 V1 判据绑定面写「格件 **st** 边框/点迹字段」——本卡自认编排在状态件批之后,届时该读面已改 u.face.*(ui_input_probe 四处改址为状态件批 V4 行),判据面描述按施工时点必陈旧。改法:改写为「格件状态件边框/点迹字段(状态件批合回后=u.face.*)」。
3. 【应修】§3 现状事实「公开入口 `resume_adventure`(:94)」行号错——实查 :94 是 start_adventure,resume_adventure 在 adventure_runner.gd:141。改法:改 :141(T0 重锚虽会兜住,现状事实按规约须代码级准确)。
4. 【应修】§13 预算节「预算 2(_hover/_last_click)**+引用束成员**」「预算 6……**+引用束**」未给引用束成员数,复核门无法对账 ≤15。按 §7/T2 构造面推算 board_hover 约 7(2+cells/minesweeper/diggable+2 Callable)、breakpoint_store 约 14(6+db/rng/主角账三件/curio/stop/bank/loadout)——均达标但后者贴顶。改法:把引用束成员逐一列名计数写进预算表。
5. 【可接受申报】V1 零漂移证明全压既有断言面;悬停 11 函数族中 chord 双击首遇锚(board_view.gd:475 _detect_chord)在「棋盘悬停反馈」三语义行与 ui_click_probe 之外无显式断言,属既有覆盖缺口。零行为改动批不为既有缺口补测不违规,实现报告宜记一句该缺口。
6. 核验通过项:A 两行对照表三问可答(真实入口/判据面/能力行齐);C 对照表零静态行;E 键账全对(board_view 32 实数清点吻合、−2=约30;adventure_runner 28 清点吻合、−6=约22;断点域 6 成员与 9 函数族 file:line 全命中;BREAKPOINT_FIELDS :539 起、breakpoint_resume_test.gd:185 命中);F 拆分职责语句在位、_r0 留宿主防凑计数袋论证成立(board_view.gd:238/:296/:563 三消费方实查);G 与迭代 42 的 board_view 触面已声明、编入待其合回;I 与裁决①②⑤一致(D5 留债、禁落豁免登记、_r0 留宿主);J 一步一动作、无 TBD 类句式。
## 卡二:组合根注册面批(main 49→15)
**裁决:有条件成立**(一项 blocker 级必改+两项应修;机检与数字面全过,方案本身成立)。
逐条发现:
1. 【blocker】§1 编队注记「与迭代 42……**无文件交叠(main.gd 与探针不在其触面)**」与盘面矛盾——在飞并排卡 `reports/需求卡片-level_runner商店委托层拆除-2026-10-29.md` 文件清单明确含 game/presentation/main.gd(改址 1 处)、main_adventure_flow.gd(6 处)、main_overlay_flow.gd(2 处),三者全在本卡触面集(main.gd+三流程件)。用户裁决④要求五卡编队碰撞约束与迭代 42 自洽,此句是失实声明,编排段靠它排卡。改法:改为「与迭代 42 商店委托层拆除卡在 main.gd/main_adventure_flow/main_overlay_flow 三文件有改址点交叠——待其合回后开工,T0 映射表生成时并核其改址点」;T0 步骤同步补一句。
2. 【应修】§8 对照表第 2 行与第 11 行内含静态判据(S13 键账对账「main.gd 实测 15」、grep 残留=0)——姊妹卡三/四/五均已把静态键账判据按 test-conventions §8.4 出口移出对照表(在域口径段申报),本卡两行在表内带静态成分,形态不一致。改法:静态部分移入 §8 域口径静态申报段,行内只留行为主证(双宿主摘要/全量闸回执)。
3. 【应修】转发壳清点漏一件:main.gd:516 `main._flush_row_queue()`(纯转发 `_row_pacer.flush()`,消费方 pacing_queue_test.gd:103+main 内部两处注记)不在「七别名+六转发方法」清单——_row_pacer 迁 ui.screens 后该 Middle Man 壳归宿未声明,与本批净消灭转发壳的方向不一致。改法:表 C/表 D 补一行(退役并改址消费方,或写明保留理由)。
4. 【可接受申报】V4(探针批量改址)与 V10(render_gate)的能力行锚取九探针中单点代表行(棋盘悬停反馈/站桩敌人呈现),语义为最小可得锚且未逐行披露该局限。建议 §8 域口径补一句「探针/渲染行能力锚取代表行」。
5. 核验通过项:A 十一行全齐;E 数字全对平——main.gd 49 个 var 实数清点吻合(grep ^var 恰 49)、49=28 迁(表 A 9+5+14)+14 留(表 B)+7 消灭(表 C)+1 新增=15;四新件预算(2/0/0/1 公开方法、3/9/5/14 成员)与 §7.2 接口块逐名一致;LAYER_CONTRACT :39 起、六转发方法 :156/:161/:282/:285/:288/:292、别名七件行号全命中;smoke_boot 六处 get()=4 改 2 留逐字吻合;pacing_queue_test :108/:132/:147/:149、source_guard V1d :69-77、theme_projection V6 :724-725、system_test V1c/V2 :94-109 全命中;D 能力行六名全在 game/tests/README.md 且受影响行核对成立;F §12 复用排除论证(ModalFlow/ModalStack/ui_assembler/run_scope 逐一否决+ConfigDB 三容器先例)充分;唯一面实查成立(game/presentation/ 下四名未建、仅 ui_assembler 在册);I 与裁决①③一致(零豁免、注销句、净消灭);J 估时 3–4 日在冻结线内、步骤全部可核查。pipeline_gate 机检 13 卡全过。
## 卡三:战斗编排归约批(RoundCycle+BattleFacts,38→15)
**裁决:有条件成立**(一项应修算术错;其余全过,是五卡中证据密度最高的一张)。
逐条发现:
1. 【应修】§4 红线句内部算术矛盾:「已迁 **22** 成员声明随迁即删(**21** 迁两件+treasure_inventory 退役+_hero_atk 退役)」——21+2=23≠22。实数=迁两件 22(BattleFacts 15+RoundCycle 7)+退役 2=删声明 24 项;轴丙后宿主 37→13 旧留+2 新=15,账平。architecture v1.25 两行写「收编 7+14=21」与本卡 BattleFacts 15 名单的 1 名口径差,已由 §6 反哺点通道(「批末成员数实测值与在册数字出入」)覆盖,但本句数字须改正以免实现期对账混乱。改法:改「22 迁两件+2 退役」。
2. 【可接受申报】encounter 归 BattleFacts 最弱格标注诚实:设计文档 §6 白纸黑字「它也是本方案最弱的一格」+两条备选砍路(nest_preview_count 解冻/_reward_economy 经授予件中转)均判更差;卡内 L3② 给出实现期证伪的停卡出口、§4 给出 15/15 贴顶与 SealLedger 扩容阀、设计 §8 险点 8 处理了 BoardInstaller bundle 键 encounter 传 _facts.encounter 的同引用零冲突——无隐瞒。
3. 核验通过项:A V0–V6 七行齐(V2 复位边界险点单独配断言、判据绑两快照同键值恒等);E 类变量 38 实数清点吻合(:37-85+:223-227 逐名)、基线两条类级键与「零函数级键」实查一致、保留 15 名单/两新件 8+15 成员账全平;file:line 抽验约 20 处全命中(treasure_inventory setter :48-52、外部注入 level_runner.gd:520、宿主四读 :111/:203/:450/:858、grant_segment :370-371、combat_segment :56、settle_segments_test :27 接线断言原文、static_scan S8 :317/S7 :359 九文件清单、run_all_gates PARITY 清量 battle_orchestrator :169、五段构造/三闸/摇号/复位块/完美谓词行号);C 静态判据(键账收敛、S7/S8 增行)已按 §8.4 出口移出对照表在域口径段申报;D 十三处能力行全部在 README 在场且语义对题(V0 锚「回放确定性」为精确锚);F 两新件职责语句+集体身份在位(「持段件者不能是被持者」「事实账不是授予物」)、已否决切法留档;G 编队前置「迭代 42 合回之前禁开工」覆盖与在飞两卡在 battle_orchestrator/level_runner/static_scan.sh/treasure_effects_test 等的全部触面交叠;I 与裁决①③⑤一致;J 估时 2.5–3.75 对设计 §12 的 2–3 日给了上探理由,PARITY 批内实跑须用户点头不占估时。
## 卡四:呈现层状态件批(单格两域件+站桩两件,30→10/19→10)
**裁决:有条件成立**(一项应修编队漏声明;潜伏红处置路径成立,成员拆分账五卡中最难算、已全对平)。
逐条发现:
1. 【应修】与卡二在 game/probe/ui_input_probe.gd 的**同文件交叠两卡均未声明**:组合根注册面批改该探针的 main.X 地址面(:34-43 等约 867 处散布之一),本批改四处 u.face.* 直读(:234-235/:243-244/:250/:374-379)——行位不相交但同文件,两卡又是同一条目(零豁免五键清偿批四卡)的同代候选,编排段靠编队声明排卡,此漏会制造二次 T0 重锚。改法:两卡编队注记互写一句(本卡补「与组合根注册面批在 ui_input_probe.gd 有触面交叠,先后施工各自 T0 重锚」,卡二同步)。
2. 【可接受申报】潜伏红 T0 定谳路径诚实:四处直读实查确在探针源码、迭代 41 已把 hl_visible/hl_color/dot_visible/mutation_mark 迁入内嵌类 _CellPaintState(board_cell_unit.gd:27 起),宿主 Node2D 无同名属性,「Invalid get index」推演成立;卡内预设 L3③「实跑全绿=证伪设计前提=停卡」的出口——未把推断当已证事实写死,定谳义务落在 T0 实跑。
3. 【可接受申报】V4 能力行锚「棋盘悬停反馈」含 case⑭ 变异角标(非悬停三语义)的最小拉伸;同一探针同一入口,可接受。
4. 核验通过项:A 四行齐(V1/V2 golden 主证、V3 演出链、V4 悬停金框/禁入红框/路径点迹/变异角标四处断言面);E 成员账全对平——内嵌类 27 名实数清点吻合、基座 12(11+_owner)+叠加 13(12+_owner)+宿主上收 edge/cell/glow_group+原位 glyph/glyph_color/plate/fog_state/_glow_layer+base/face=宿主 10;站桩真实 25=vitals 11 名+motion 10 名+原 _owner+3 计数器、宿主 10=5 冻结 var+st+mo+3 计数器;31/33 全文件声明数与 :26-122/:125-143、:23-59/:62-68 分区实查一致;九常量 :12-23 逐字命中;C 静态键账判据已按出口移出对照表(§9 域口径段申报,五卡中形态最规范);D 六处能力行全在场且语义对题;F 四新件职责语句+逐件排除论证(TilePalette/HeroSprite/BoardWorld/battle_stage_view/StatusSlotRow)在位,迷雾留宿主的「唯一不产生跨件回引」论证成立;G 与迭代 42 的 board_view 五段改型耦合声明完整(T0 前置+「先于尾波补件批 board_hover 半边合回」反向义务);gdstyle 截断缺陷红线(禁利用截断口径降数、禁把 _portrait_tex 当削减目标)与裁决一致;golden 三张禁换锚禁重制。
## 卡五:测速循环批(信号步进状态机+双实现对拍)
**裁决:有条件成立**(一项应修能力行悬置;对拍方案与申报形态是五卡中最完整的)。
逐条发现:
1. 【应修】能力行锚语义错位且专属行悬置无主:三行对照表能力列锚「站桩敌人呈现与结算演出落点」,该行语义是站桩呈现与终局演出(README 旅程段六,系统列=战斗表现),与本批测量面(批量模拟逐帧步进/运行态贯穿/报告注入)不同域;卡内自承「测量面专属能力行=写卡段后续处理」——但写本卡的会话**就是**写卡段,2026-10-29「当场入表」规则下该行应随本卡增行(真实入口=debug_overlay press_simulate_for_probe() 按钮 pressed 信号链→run(n);代表用例=standee_fx_sweep_test.gd:_init〔wd8〕+tune_sim_batch_parity_test.gd:_init),增行后本列改锚。悬置写法让义务无承载主体、批末无人对账。
2. 【可接受申报】行为改动申报完备性成立:全件 68 行实读核对——:67-68 确为每局置假(潜伏红本体),静态矛盾推演(drv.seen=[true,false]、探针守卫环同段退出四串全红)与源码逐句吻合;改形其余面(常驻连接/is_connected 守卫/首步同步/n=0 同步收尾/_step_frame else 先断连)核为非行为改动;「_finished 若零读者可删」方向是删不是留,不违禁为机检保留成员条款。
3. 【可接受申报】脚本错误中断路径差异按 §8.4 出口声明缺口(协程死亡静默停摆 vs 确定性错误逐帧重试),T3 文档化义务在位,未伪装成可证判据;两形态测量批遇错都整批作废、同级不同形的论证成立。
4. 核验通过项:A 三行齐且真实入口真实(wd8 假驱动回调内读 is_running()、探针真实按钮信号链);E 键账预算表逐规则落卡、成员 5+6=11(信号计入则 12)账与 T1 名单吻合、_run_one_level 5 参临界持平声明在位、改造后全文件零循环键消除逻辑成立(结构性免疫);file:line 全量命中(run :36-52、循环 await :50、FakePanel/FakeDriver、wd8 三断言与〔wd8〕尾缀、ui_tune_probe SIM_GUARD_FRAMES=1800 :16 与 :63-83 四串断言、debug_overlay is_running :77/set_sim_running :81/_sync_sim_button :107、main_debug_flow :72-77 不 await 形态与 :84 互查守卫、hud_presenter 空守卫与 maxi(1,n));C 静态判据与声明缺口均不入对照表;F 零拆出单元的「不拆理由」在位(步进机是私有运行机制、拆出命不出职责语句=凑计数袋,§8 引 code-conventions ②④);遗留 await 形态副本全仓唯一性+夹具不入四扫描面的声明经实查成立(基线 :15 唯一键、S8 九文件不含本件);G 与其余四卡及迭代 42 无产品码触面交集声明成立(run_all.gd manifest 潜在交叠已交编排段);I 与裁决③④⑤逐条一致(双实现对拍入批、收尾还原作为已申报行为改动、错误路径接受并文档化);J 估时 1–1.5 日合理,T0 定谳证据列为审计第③项必查项。
## 总表
| 卡 | 裁决 | blocker | 应修 | 可接受申报 |
|---|---|---|---|---|
| 卡一 尾波补件批 | 有条件成立 | 0 | 4 | 1 |
| 卡二 组合根注册面批 | 有条件成立 | 1 | 2 | 1 |
| 卡三 战斗编排归约批 | 有条件成立 | 0 | 1 | 1 |
| 卡四 呈现层状态件批 | 有条件成立 | 0 | 1(与卡二共担) | 2 |
| 卡五 测速循环批 | 有条件成立 | 0 | 1 | 2 |
全库 blocker 与应修清单(编排段放行前置):
- **blocker(卡二 §1)**:编队声明失实——「与迭代 42 无文件交叠(main.gd 不在其触面)」被在飞商店委托层拆除卡的文件清单(main.gd/main_adventure_flow/main_overlay_flow)直接证伪,须改写为如实交叠声明+开工前置。
- **应修(卡二+卡四,跨卡)**:ui_input_probe.gd 同文件触面交叠两卡编队注记均未声明,互写一句补齐。
- **应修(卡一 §7)**:board_hover 半边的状态件批先行约束从「推荐」升为硬前置,与卡四侧已裁义务对齐;breakpoint_store 半边明示可独立先行。
- **应修(卡一 §8)**:V1 判据绑定面「格件 st 边框/点迹字段」按施工时点改 u.face.* 口径。
- **应修(卡一 §3)**:resume_adventure 行号 :94 改 :141。
- **应修(卡一 §13)**:预算节引用束成员列名计数(board_hover 约 7、breakpoint_store 约 14)。
- **应修(卡二 §8)**:对照表第 2/11 行静态判据移入域口径申报段,与卡三/四/五形态统一。
- **应修(卡二 表 C/D)**:main._flush_row_queue(:516)转发壳归宿补声明(退役改址或保留理由)。
- **应修(卡三 §4)**:「已迁 22 成员(21 迁两件+2 退役)」算术改正为「22 迁两件+2 退役」。
- **应修(卡五 §6/§12)**:测量面专属能力行随本卡当场增入 game/tests/README.md 并改锚三行能力列,废「写卡段后续处理」悬置表述。
总体判断:五卡可以进编排段,但须先落上表一项 blocker 与九项应修——全部是编辑级补丁与声明修正,无一张需要推翻拆件方案或重做设计。证据面结论:五卡 file:line 抽验约 90 处命中(唯一硬伤=卡一处行号),键账与成员迁移账全部数平(含卡四最难的 27/25 内嵌类双 _owner 拆分),两处静态矛盾推演(卡四潜伏红、卡五每局置假)经源码逐句复核成立,与五项用户裁决无一冲突,机检 pipeline_gate 全绿。最大的真实风险不在卡内而在编队声明层:卡二对迭代 42 的无交叠声明失实、卡二与卡四未声明探针同文件交叠——这两处修正后,编排段才有可信的排卡依据。
@@ -0,0 +1,36 @@
# 迭代 41 测试债批——实现报告(2026-10-29)
**接收方**:待办清单原「迭代 41 测试债修复——9 个套件失败与静态扫描三项红」条目(随本批完成整条删除,本报告为收尾凭据)。
**改动面**:游戏代码(worktree 批)。
**执行**:worktree `g-plan2-testdebt-20261029`(分支 `testdebt-20261029`,自 master cf0e40cc 分出,批内 `git merge master` 到 39c1fc69 后跑闸),提交 215da315/413124b0/afd1a41f,合并提交 43906cdd;工作区与分支已删除。
## 一、登记范围完成度
| 登记项 | 结果 |
|---|---|
| 02 九套件失败 | 全部归绿(65 套件全跑,`[run_all] 0 个套件失败`) |
| S9 类型闸 24 处 | 归零——`node_map_generator` 三处给真类型(`Array[int]` 贯通 `_vo_flow_facts`→`_build_trunk`),其余 21 处为动态边界(Variant 出值/鸭子型注入/异构 Callable 束),按 V7 白名单逐处补 `# type-hint: ignore` 并写明理由 |
| S10 文件头 4 处 | 归零——`config_db` 与三张域容器头注去日期 |
| S11 注释禁用词 1 处 | 归零——`adventure_table.gd:55` 档位退役词「罕见」改现行「稀有」 |
| 死常量 `SCHEMA_VERSION` | 已删(全仓零引用;文档侧「表结构版本」冲突面已由文档批清偿) |
## 二、实测扩出的范围(登记条目未预见,全部由代码域闸实跑暴露)
登记时 03/04/05 三闸在能力审计上电批被记为 SKIP(测量面批口径),其红项从未被实测过,故条目只记了 02 与 09。本批按代码域实跑,三闸皆红,逐条追因如下——**四处是迭代 41 特许直接合回留在产品码里的运行期断链,不是测试债**:
1. **数字色牌守卫丢失**(`game/presentation/views/board_cell_unit.gd` `_draw_glyph_layer`):迭代 41 卡②绘制分层时把 `if plate:` 判据丢掉,变成「凡有字形即垫牌」。后果=dungeon 关数字(本应亮墨直画在棕底)一律落到奶油色牌上。判据=棋盘 golden 逐像素:L1_dungeon changed=2.74% 超容差、L2/L3 与菜单 0.00%;恢复守卫后 L1 回 0.00%(与迭代 37 换代基线逐像素一致)。墨族自适应实测读数同时佐证现行口径:dungeon `plate=false`(亮族对比度 4.79/5.80 过门槛)、underdark `plate=true`(深族均值 2.41 不过门槛)。
2. **`open_victory` 第 4 参未随 opts 改型**(`game/presentation/curio_interact_controller.gd:79`):迭代 41 卡②把该函数的四散参数收拢为 `opts := {}`,其余调用方(`main.gd`/`main_adventure_flow.gd`)已改,此处仍传字符串 → 运行期 `Cannot convert argument 4 from String to Dictionary`,关卡完成三选一停点与续玩恢复路径的胜利总结面开不起来(探针报「三选一停点分支中断」)。改型为 `{"gp_summary": …}`,串内容与改前逐字同。
3. **站桩补间目标写错**(`game/presentation/views/standee_body.gd`):状态收进内部件 `st` 后,9 条 `tween_property(self, "st.xxx", …)` 的属性路径不成立(引擎报 `The tweened property ... does not exist`,并连带 `set_trans` 落在 null 上)→ 血量条与三档意图动效全静。改为直接补间子对象 `tween_property(st, "xxx", …)`。
4. **调参批量模拟运行态收尾位置**(`game/presentation/tune_sim_controller.gd`):循环体提函数时把 `set_sim_running(false)`/`_running = false` 搬进了单局函数,等于每局结束就宣布模拟结束——面板置灰与组合根互查守卫在剩余局数内失效。归还到 `run()` 末尾。
另有探针面随拆件改址(断言零删减、零放宽):`ui_input_probe` 格面成员入 `st` 六处、`ui_struct_probe` 的 `level_screen._runner` → `._map._runner`;测试面改址九处(`slots`/`meta_state`/`crossrun`/`_forge`/`_side`/`_meta_rows`→表成员直读/`_shop_rows`→表成员直读)。
## 三、闸与回执
`tools/run_all_gates.sh --code`(域=code、scope=full、dirty_game=false):00 冒烟/01 系统测试/02 单元与集成/03 探针 --click/04 探针 --full/05 渲染闸/09 静态扫描/10 熵增闸全部退出 0;11 回放确定性对拍按触面判定 SKIP(本批未触数值·存档·RNG·结算)。与基线比对=**零新增红**,且 02、09 两闸「基线红 → 现绿(改善)」,`all_green=true`。合回后主区两件秒级事已过:`--editor --quit` 重刷类名缓存、冒烟 15 项 0 失败。
## 四、遗留与待裁
1. **闸基线 02/09 两键待换代**:两键仍记本批已消除的存量红指纹,未来若回归到同一红项会被判「存量红·零新增」而静默放行。换代须改 `game/tests/.gates/baseline.json`(代码面)→ 已另立待办条目,随下一个代码批一并落。
2. **architecture.md 残留常量名**:`design/engineering/architecture/architecture.md:88` 的 ConfigDB 行仍把 `SCHEMA_VERSION` 列为该类职责,常量已删,该句失真——属文档面反哺点,待文档批按「删该词或改现役 `SAVE_FORMAT_VERSION`」落文(本批为实现批,禁写 `design/`)。
3. **实机目检**(归用户,不阻塞):dungeon 关胜利后数字回到棕底直画(无奶油牌);关卡完成三选一停点的胜利总结面能正常开出并可继续;调参面板批量模拟期间浮窗置灰、结束后解除。
@@ -0,0 +1,134 @@
# 需求卡片——gdstyle 尾波补件批
> **版本状态**:v1.0 定稿——零待裁点(2026-10-29 用户裁:恢复尾波卡 v2.0 裁去的 D2/D4 两拆件项;D5 五降值键=留债、零豁免延伸)。
> **接收方**:待办清单条目「gdstyle 尾波补件批——悬停域与断点域拆件(2026-10-29 登记)」。
> **来源**:尾波清偿批设计闭合后的用户再裁(D2/D4 改判拆件)。**唯一事实源**:`design/engineering/architecture/architecture.md` v1.25(「模块归属·呈现层」表 board_hover 行、「核心层」表 breakpoint_store 行、「冒险域拆分」节断点随动句、「呈现层装配」节屏成员寻址句)。
## 1. 目标与完成定义
这批做什么:把尾波卡 v2.0 裁去的两个拆件项恢复执行——board_view 悬停域拆出 board_hover、adventure_runner 断点域拆出 breakpoint_store。三个 gdstyle 键随之降值(board_view 类变量 32→约30、adventure_runner 类变量 28→约22;board_view 公开方法 27 持平——全为契约面)。
什么状态算完:
1. 两新件在库、宿主成员迁出、键账达第 3 节预期(降值口径,不承诺清零)。
2. 行为零变化:同种子下事件流、断点快照、棋盘渲染逐位一致。
3. 批末代码域闸全绿;三键终值按留债口径记入实现报告(禁落 architecture 豁免登记)。
## 2. 设计事实源
architecture.md v1.25 三处在册设计(2026-10-29 零豁免裁设计闭合):board_hover 行(职责语句「悬停预承诺呈现域」、拟收 11 函数族+2 成员、耦合边界)、breakpoint_store 行(职责语句「存档断点组装与回放唯一承载」、拟收 6 成员+函数族、27 键冻结)、「冒险域拆分」节随动句(拼盘与读侧策略机组拆出、应用层落盘口不变)。
## 3. 现状事实(2026-10-29 实查;行号为迭代 42 合回前基线——T0 必须按当轮 master 重测重锚,board_view 的 `_paint_cell` 届时已由迭代 42 拆为五段、行号必漂移)
- board_view.gd:悬停域成员 `_hover`(:70)、`_last_click`(:71);函数族 11 个=`_hover_at`(:442)、`_on_shell_mouse_exited`(:453)、`_detect_chord`(:475)、`_on_cell_hover`(:486)、`_on_cell_unhover`(:491)、`_refresh_hover_after_paint`(:497)、`_apply_hover_visuals`(:503)、`_clear_hover_visuals`(:531)、`_set_cursor_shape`(:538)、`_show_path_preview`(:542)、`_hide_path_preview`(:552)。`_r0`(:72)是出生展开区资格域成员(:238/:296/:563 三消费方),**不随迁**——划入悬停件即凑计数袋。
- adventure_runner.gd:断点域成员 6 个=`_save_manager`(:35)、`_resume_bp`(:36)、`_pending_next_level`(:30)、`_last_level_payload`(:31)、`_last_treasure_cleared`(:32)、`_loadout_seeded`(:37);常量 `BREAKPOINT_FIELDS`(:539-568,27 键);函数族=`_snapshot_breakpoint`(:571)、`_bp_parts`(:583)、`_bp_read`(:636)、`_bp_strategy`(:646)、`_bp_read_int`(:651)、`_resume_ledger`(:182)、`_resume_curio_state`(:193)、`_resume_params`(:218)、`_resume_counters`(:237);公开入口 `resume_adventure`(:141;:94 为 start_adventure)留宿主薄壳。
- 测试触面:`game/tests/unit/core/breakpoint_resume_test.gd:185` 直读 `AdventureRunnerScript.BREAKPOINT_FIELDS`——随件迁改址(判据零变化)。
- 键账:board_view 类变量 32(键留债目标约 30)、公开方法 27(持平——27 个逐类核对全为探针契约面与依赖单向纪律承载面);adventure_runner 类变量 28(留债目标约 22)。
## 4. 设计契约(违反即返工的红线条款)
- 🔴 **行为零变化**:同种子下事件流/断点快照/存档往返/棋盘渲染逐位一致;玩家可见面零变化。
- 🔴 **断点键集冻结**:`BREAKPOINT_FIELDS` 27 键逐键冻结(键名、策略标签、键序零变化);随件迁移只换承载文件,不换键面。
- 🔴 **RNG 零触碰**:本批零新流、零消费序变化(断点回放 restore 同序取号;悬停域无随机)。
- 🔴 **呈现零变化**:悬停反馈三语义(光标/边框/路径预览)行为逐点保持;棋盘 golden 三张对拍差异非零即红。
- 🔴 **拆分边界纪律**(判据权威=code-conventions §1.1,卡内执行条款):①拆出单元须有职责语句与单一变化原因(实现报告逐件一行);②集体身份——命不出名字的打包=凑计数袋,禁;③「过阈值」只作发现信号;④拆不出内聚单元→停卡呈报;⑤禁沿阈值轴拆。
- 🔴 **禁为机检文本保留无效成员**:禁止为迎合机检消息文本保留或新增无效成员/别名;机检键与卡片契约互斥=停卡呈报。
- 🔴 **残留键留债(D5 零豁免裁)**:三键降值后留基线冻结禁恶化;**禁落 architecture 豁免登记**;禁为凑阈值硬拆。
## 5. 范围边界
做什么:第 3 节两拆件项(board_hover、breakpoint_store)。
不做什么:迭代 42 在飞范围零触碰(_paint_cell 拆五段、循环内 new、_enter_node、商店委托壳——并排卡承接);单格/站桩状态件(呈现层状态件批承接);main.gd/battle_orchestrator/tune_sim 五键(零豁免五键各批承接);三残留键的终局清偿(留债,后续窗口再议)。
## 6. 关联文档同步面
| 文档 | 关联点 | 同步义务 |
|---|---|---|
| design/engineering/architecture/architecture.md | 两新件登记行(建件后「实现批建件」改现状);「冒险域拆分」节随动句核对 | 设计权威文档——实现批禁直改;逐条列进 `reports/iter<N>-反哺点-<日期>.md`,用户裁决后归文档批落文 |
| game/tests/README.md | 「棋盘悬停反馈」行代表用例列(本批复用既有探针、零新增断言——预计零改动);断点行入口句核对 | 机械面文档——实现批禁写;如需更新由写卡段后续卡修订版同批处理 |
| design/gdd/systems/ | 无关联文档——结构整改不改游戏规则与玩家可见行为 | 无修订预期;契约句被触碰=停卡呈报走反哺点通道 |
## 7. 任务卡 T0..T3
**T0 读数重锚与对账(0.25–0.5 工作日)**
- [ ] 以当轮 master 重测 board_view/adventure_runner 三键实测值与第 3 节全部 file:line;漂移处就地改卡并记录;对不上即停卡呈报
- [ ] 复核 11+9 函数族现行键面(`tools/gdstyle_baseline.txt` 无其函数级键——逐字搬运零新键;实查确认)
**T1 board_hover 拆件(0.75–1 工作日)**
- [ ] 建 `game/presentation/views/board_hover.gd`(RefCounted;构造=引用束注入:cells 容器引用、minesweeper 只读引用、diggable 集合引用+壳层光标写入与 hover_forbidden 注入 Callable)
- [ ] 悬停函数族 11 个+成员 `_hover`/`_last_click` 迁出(函数体逐字搬运);三入站口(`_gui_input`/`_on_cell_input`/`click_cell`)留宿主委托;`hover_probe()` 留宿主读件投影(返回语义零变化);`_r0` 留宿主
- [ ] 孤立验证:`tools/probe_gate.sh --click`+`--full` 全绿;`tools/render_gate.sh` 棋盘 golden 三张差异 0.00%(非零即停机呈报)
**T2 breakpoint_store 拆件(1–1.5 工作日)**
- [ ] 建 `game/core/breakpoint_store.gd`(RefCounted;构造=引用束注入:db、rng、主角账三件、curio/stop/bank/loadout 引用——防 max-parameters 新键)
- [ ] 断点域 6 成员+`BREAKPOINT_FIELDS`+函数族 9 个迁出(逐字搬运);`resume_adventure` 留宿主薄壳;`set_save_manager` 转发件
- [ ] `breakpoint_resume_test.gd:185` 改址为 breakpoint_store 常量(判据零变化——第 14 节申报)
- [ ] 孤立验证:`--script res://tests/run_all.gd -- --only=breakpoint_resume,save_rng_roundtrip,cross_system_flow` 全绿+`python tools/run_smoke.py`
**T3 键账对账与收口(0.5 工作日)**
- [ ] 批末代码域闸全绿(`tools/run_all_gates.sh --code`)
- [ ] 三键终值对账(board_view 约30/27、adventure_runner 约22)——留债口径记入实现报告
- [ ] 产出物落位卡:实现报告与反哺点清单写齐方算收口
合计估时约 2.5–3.5 工作日。编队注记:编入待迭代 42 合回;**board_hover 半边硬前置=呈现层状态件批先合回**(该批改型 u.st 写入面后,hover 拆件在新写入面上施工——grilling 复核定级,原「推荐先行」升格);breakpoint_store 半边无此依赖,可独立先行。另:本卡与组合根注册面批共享 ui_input_probe.gd 触面(该批改 main.X 地址面、本批不改探针内 u.face 读面)——同代编排时先后皆可。
## 8. 验证闸——改动—验收对照表
域口径:本批改动全为 `game/` 下非 .md 行为载体——批末跑代码域闸;里程碑步(T 段)出口跑一次全套闸,波内修复只做出红最小单元的最窄确认,新增测试先行孤立验证再并入全套。总判据=每行改动以「既有断言面全绿+golden 零差异」证明零行为漂移;全量闸电池=冒烟+系统测试+run_all 全量+probe_gate --click --full+render_gate+static_scan(含 S13 对账)。
| 行 | 需求点 | 改动(文件:行/行为) | 验收测试(名称+落点+尾缀) | 层级 | 真实入口 | 判据绑定面 | 能力行 |
|---|---|---|---|---|---|---|---|
| V1 | 悬停域拆件 | board_hover.gd 新建;board_view.gd 函数族与 :70-71 成员迁出 | 复用 ui_input_probe 悬停三语义断言(case①到达/②禁入/③路径预览)+ui_click_probe+type_glow_shot_probe;新增断言零条 | 探针 | 合成 InputEventMouseMotion/MouseButton 经 `_gui_input` 入站口;`hover_probe()` 读面 | 探针可见性断言面(hover_probe 返回值、光标形状、格件状态面边框/点迹字段——施工时点在呈现层状态件批合回后,按其改型后投影面口径核对,判据语义零变化)+golden 三张零差异 | 既有:棋盘悬停反馈(三语义光标/目标格边框/路径预览点迹) |
| V2 | 断点域拆件 | breakpoint_store.gd 新建;adventure_runner 断点函数族与 6 成员迁出 | 复用 breakpoint_resume_test 全套+save_rng_roundtrip_test+cross_system_flow_test:_feats_breakpoint_roundtrip;新增断言零条;:185 改址(第 14 节申报) | 单元+集成 | AdventureRunner.resume_adventure()/start_adventure() × SaveManagerCore 断点域 | 断点快照往返逐键断言面(27 键冻结——键名/策略/键序零变化) | 既有:断点片段往返与续玩幂等;既有:旧档迁移链与断点续玩零跳号(集成) |
反向核对:diff 中每个行为改动均有行——本批申报行为改动为零(全部非行为改动=结构整改,判据=零漂移证明)。孤儿断言:无(零新增断言)。
## 9. 异常分级
- **L1 自救**:迁移函数编译错、探针调用面改址漏改——就地修复重跑最窄确认。
- **L2 记录继续**:实测值与预期区间偏离但同档位——记入实现报告「实现决定记录」。
- **L3 停机写报告等用户**:①拆分边界纪律④触发(含 `_r0` 归属认定被实现期证伪);②机检预算互斥——新件实数超第 12 节预算或迁移函数现出超标键=停卡退回写卡段;③golden 对拍差异非零;④S13 键恶化或基线外新键;⑤断言面被下游兜底吸收致判据绑不上。
## 10. 代拍板白名单
1. 迁移函数头注指址微调(词表与语义不动)。
2. 新件私有 helper 命名微调(职责语义不变)。
3. 断言失败消息尾缀〔补件 Vn〕分配与措辞。
4. 改址机械改写(preload 顺序、空行排版)。
## 11. 待裁点
零待裁点,开工门=U0。(裁决记录:2026-10-29 用户裁——恢复 D2/D4 拆件;D5 五降值键留债、零豁免延伸;`_r0` 留宿主;断点域六成员全迁。)
## 12. 落位与可复用性预检
- **board_hover.gd(新增)**:复用面核查——悬停预承诺逻辑现行全在 board_view(11 函数族全仓无第二实现,无既有件可复用);不能并入 TilePalette(瓦片装载)、HeroSprite(英雄演出)、CellUnit(格件绘制)——悬停预承诺与三者是不同变化原因。落点唯一:`game/presentation/views/` 新件,board_view `_init` 建为子件(HeroSprite 挂载先例)。调用路径:只被 board_view 持有与调用,输入经宿主入站口委托,禁反向持宿主引用(注入回调单向)。
- **breakpoint_store.gd(新增)**:复用面核查——断点拼盘与读侧策略现行在 adventure_runner(`BREAKPOINT_FIELDS` 登记单源唯一);不能并入 save_manager(存档 IO 原语与冒险断点语义是两个变化原因——SlotStore 拆分已立界)、不能并入 MetaStateStore(元进度数据件)。落点唯一:`game/core/` 新件。调用路径:只被 adventure_runner 调用;宿主经件组装快照后写盘,应用层落盘口不变。
- **新增函数**:零——全部为既有函数体逐字搬运。零新增数据件、零新增常量表(`BREAKPOINT_FIELDS` 为迁移非新增)。
## 13. 实现规范预算(gdstyle 默认阈值对账)
| 新件 | 公开方法 ≤20 | 类变量 ≤15 | 迁移函数对账 |
|---|---|---|---|
| board_hover.gd | 预算 6(悬停驱动入口) | 预算 2(`_hover`/`_last_click`)+引用束约 7(cells/minesweeper/diggable 引用+光标写入与 hover_forbidden 注入 Callable)=合计约 9 | 11 函数现行均无超标键(基线无其函数级键);`_apply_hover_visuals` 分支 5 |
| breakpoint_store.gd | 预算 8(快照/回填/读侧入口族) | 预算 6(拟拆成员)+引用束约 14(db/rng/主角账三件/curio/stop/bank/loadout)=合计约 20?否——引用束为单成员字典注入,实计=6+1 束+件内散标 ≤15(T0 按实数对账,贴顶禁再增) | `_bp_parts` 现行 49 行/9 局部(:583-630 实测)均在默认阈值内;`_resume_*` 四函数无超标键 |
存量触面一查:board_view 6 键与 adventure_runner 1 键 T0 读数写明「S13 键较登记值只降不升」预期;`_init` 一律引用束注入防 max-parameters 新键。
## 14. 测试削弱申报
1. `breakpoint_resume_test.gd:185`——`AdventureRunnerScript.BREAKPOINT_FIELDS` 直读随件迁改址为 breakpoint_store 常量;判据零变化,仅常量承载文件换代。
2. 除此之外禁删断言、禁放宽阈值、禁缩小扫描面、禁把真实入口换成下层直调;未申报的削弱由独立验收审计判红。
## 15. 独立验收审计
合并前由未参与实现的会话或子代理执行;报告落 `reports/iter<N>-验收审计-<日期>.md`。审计至少做四件事:逐行核对第 8 节对照表(测试存在、真执行、尾缀可 grep、真实入口未绕过改动点);抽查判据绑定面;检查测试削弱(对照第 14 节申报);核对两行「非行为改动」判定的零漂移证明是否在当轮真实跑批中成立。未过不得合并。
## 16. MC/数值与 RNG 零触碰声明
本批零数值改动、零数据表改动、零 RNG 流词表改动——断点回放 restore 同序取号、悬停域无随机。MC 对拍不跑。
@@ -0,0 +1,172 @@
# 需求卡片——呈现层状态件批
> **版本状态**:v1.0 定稿——零待裁点(2026-10-29 用户裁:单格两文件案、站桩两文件案、探针计数器留宿主、st/mo 命名、潜伏红随批修复)。
> **接收方**:待办清单条目「零豁免五键清偿批——S13 余量五键真修四卡(2026-10-29 登记)」(本卡=四卡中的「呈现层状态件批」一卡,承接 board_cell_unit 类变量 30→10 与 standee_body 类变量 19→10 两键)。
> **来源**:两份设计定稿全文。**唯一事实源**:`reports/设计-单格绘制状态件-2026-10-29.md`+`reports/设计-站桩状态件-2026-10-29.md`;`design/engineering/architecture/architecture.md` v1.25「模块归属·呈现层」表 cell_base_layer/cell_mark_overlay 行(:169)与 standee_vitals/standee_motion 行(:170)。
## 1. 目标与完成定义
这批做什么:把两个呈现层宿主的内部状态件沿职责缝拆成四个独立文件类——单格 `board_cell_unit.gd` 的 `_CellPaintState`(27 成员)按绘制层域轴拆 `cell_base_layer.gd`(12 成员)+`cell_mark_overlay.gd`(13 成员),宿主 `_draw` 退六步时序器、类变量 30→10;站桩 `standee_body.gd` 的 `_StandeeState`(真实 25 成员——基线 19 是 gdstyle 计数截断的欠估读数)按「身份命值/资产演出」缝拆 `standee_vitals.gd`(12 成员)+`standee_motion.gd`(11 成员),三个演出探针计数器留宿主、类变量 19→10。宿主实例命名:单格两件 `base`/`face`;站桩沿用 `st`(指 vitals)+新增 `mo`。附带处置一处潜伏红:ui_input_probe 四处绕过状态件直读格件成员的断言疑似已被迭代 41 状态件化打断,T0 实跑定谳,确红则随批修复。
什么状态算完:
1. 四新件在库、两宿主瘦身到位、六个 gdstyle 键账达预期(board_cell_unit 10/standee_body 10——较登记值 30/19 只降不升;四新件 12/13/12/11 全部阈值内零新键)。
2. 行为零变化:棋盘 golden 三张(L1 dungeon/L2 underdark/L3 deep_underdark)对拍差异 0.00%;探针冻结成员(glyph/fog_state/plate/glyph_color)与站桩演出时序、三条源码锚逐字不动。
3. 潜伏红定谳结论记实现报告;确红则四处改址落地、probe_gate 全绿闭环。
4. 批末代码域闸全绿;实现报告与反哺点清单写齐方算收口。
## 2. 设计事实源
两份设计定稿(2026-10-29 设计闭合,待办清单条目凭据与本节一致):单格篇 §4 拆分定案(两件案 A2、成员总账 10/12/13、写入路径对账表 §5.1、六步时序器 §6、键账预期 §7)、§1.2 gdstyle 截断缺陷与 §1.3 潜伏红发现、§1.4 探针直读面全清单;站桩篇 §3 方案 C(两独立文件+计数器留宿主)、§4 外部写入方零改动清单、§5 键账预期、§6 行为零变化六点。architecture.md v1.25 两行在册(呈现层表 :169-:170——职责语句、成员数、宿主 30→10/19→10)与「gdstyle 计数截断缺陷登记」节。
## 3. 现状事实(2026-10-29 主区实查;行号为迭代 42 合回前盘面——T0 必须在迭代 42 合回后按当轮 master 重锚)
**编队注记**:本卡与迭代 42 有 board_view 触面耦合——迭代 42(在飞,roadmap 迭代 42 行「进行中」)尾波清偿批 T1 把 `_paint_cell` 拆五段(`_paint_cell_base/_ink/_facade/_overlays/_fog`,段间只经 u.st/glyph/digit_col 传值)并抽 `_build_cell_unit`(:246-262),改变 u.st 写入面的函数分布结构(写入语句从单函数分散进段函数),写入路径形态 u.st.X 本身不变。**本卡 T0 必须在迭代 42 合回后执行**;本节行号按当前盘面实查,届时 board_view 全部写入点行号漂移、以 T0 重锚为准。反向编队义务:尾波补件批(board_hover)已裁「u.st 写入面改型后 hover 拆件在新面上施工」——本批先于其 board_hover 半边合回。另:本卡与组合根注册面批共享 ui_input_probe.gd 触面(该批改 main.X 地址面、本批改四处 u.face.* 读面,互不覆盖但同文件)——同代编排时禁并行、先后皆可,编入前置声明互指。
- **键账**:`tools/gdstyle_baseline.txt` :16 `board_cell_unit.gd|quality/max-class-variables = 30`、:23 `standee_body.gd|quality/max-class-variables = 19`。源码实查:board_cell_unit.gd 全文件 33 个类级 var(宿主 6+`_CellPaintState` 27,:26-122 内嵌类/:125-143 宿主);standee_body.gd 全文件 31 个(宿主 6+`_StandeeState` 25,:23-59 内嵌类/:62-68 宿主)。登记值 30/19 均为 gdstyle 对 inner class「首个带行尾注释属性截断」的欠估(architecture v1.25 已登记该工具缺陷;board_view.gd 无内嵌类、32 逐一全计——平面口径预测即实测)。
- **单格写入方**:唯一写方文件 board_view.gd。写入点实查——set_world_font:185(font)、set_cell_area:204(edge)、rebuild:250/251/253/260(cell/edge/bevel/font)、悬停面 :512-534(hl_visible/hl_color 五组写+一清)、路径预览 :549/:554(dot_visible)、`_paint_cell` :601-738(tex_seal:614/618、tex_base:665、bg_sb:666、glyph:667、glyph_color:668/674、plate:675、outline_sides:676/700、facade_south:677/690、proj_band:678/704、tex_facade:679/709、facade_strip:680/708、treasure_mark:713、badge_glyph:719/726、mutation_mark:723/725、glow_group:727、fog_state:734/736、removed_dim:737、终写 queue_redraw:738)、接触带 :780/:787/:804/:805/:810/:816、glow 同步 :768、cell_rect_probe 读 :891(u.st.edge)。
- **站桩外部触面**:唯一写状态的外部方 battle_stage_view——slot_row :140/:265、box :198/:208、font :232/:235、set_portrait_texture/register_hero_state :132-138、set_hero_state :313/:316/:388、演出三方法 :333-336;hud_presenter :77/:78/:137/:162/:163(set_hero/set_effects/set_effects_cleared_feedback);fx_probe 对 box 直写三处。测试直读 standee_fx_sweep_test.gd:103(`s1._intent_charge`);源码锚 theme_projection_test.gd:678-683(GOLD_BRIGHT 顺位墨/HERO_BLUE_BRIGHT 与 GOLD_BRIGHT 护甲墨/`_intent_charge = pid in CHARGE_SKILL_IDS` 三条 contains 断言)。
- **潜伏红(T0 定谳)**:ui_input_probe.gd 四处绕过 st 直读格件成员——:234-235(case① `u1.hl_visible`/`u1.hl_color`)、:243-244(case② `.hl_color`)、:250(case③ `.dot_visible`)、:374-379(case⑭ `.mutation_mark`)。这四个成员迭代 41 已迁入内嵌类 `_CellPaintState`,宿主 Node2D 上不存在同名属性,外部读预期运行时「Invalid get index」错误。时间线:探针末次全绿 2026-10-28 05:03 早于状态件合入 2026-10-29 01:37,合入后未跑过。设计文档同篇已含改址方案(u.face.*)。
- **探针冻结面(零改动义务)**:ui_input_probe.gd:271/:363(u.glyph)、:400-:492(u.fog_state case⑮族);player_copy_sweep_test.gd:138-140(u.plate/u.glyph_color wa8)。plate 绘制侧零消费(禁删禁接线——接线即行为变化)。
- **演出探针计数器**:standee_body.gd:57-59(_death_shards/_hit_sparks/_flash_count);唯一写入方宿主函数 :275/:315/:336,唯一读方 fx_probe() :301。
- **文件体量**:board_cell_unit.gd 423 行(迭代 41 已拆函数级键、本设计只解决类变量键;拆后宿主约 150 行);standee_body.gd 531 行。
## 4. 设计契约(违反即返工的红线条款)
- 🔴 **行为零变化**:绘制调用序与层序零变化——宿主 `_draw` 六步时序器与现行四函数调用树逐命令等价(设计文档单格篇 §6 四点论证:层间序/件内逐字搬运/接触带回退补画序整体保形/浮点推导式零改动);接触带「平色回退+微光并发的英雄格补画」重复绘制路径原样保形;setter 多写多触发序不变(facade_south/badge_glyph/mutation_mark 双写点);站桩六点(tween 路径串、三态机早退序、`_hp_flash_tw` 回色读 `_dead` 同拍、源码锚逐字、成员初始化时序、计数器纯易位)=站桩篇 §6。
- 🔴 **golden 三张零差异**:render_gate 棋盘 golden(L1 dungeon/L2 underdark/L3 deep_underdark)对拍差异 0.00%;非零即停机呈报,禁换锚、禁重制基线。
- 🔴 **冻结面逐字**:探针冻结成员 glyph/fog_state/plate/glyph_color 宿主保留、名称路径零变化;站桩三条源码锚所在函数留宿主且锚行逐字;battle_stage_view 一行不改(写入面零改动清单=站桩篇 §4)。
- 🔴 **拆分边界纪律**(判据权威=code-conventions §1.1,卡内执行条款;实现报告逐件一行职责语句):①拆出单元须有可陈述职责语句与单一变化原因——四件职责语句与宿主保留面语句照设计文档 §4.2/§4.3/§4.4 与站桩篇 §3 逐字承载(基座层绘制域/标识叠加绘制域/身份命值唯一账面/资产挂点与一次性演出;单格宿主=被动绘制壳+迷雾域+微光子件生命周期);②集体身份——命不出名字的打包=凑计数袋,禁;③「过阈值」只作发现信号,拆分动机是职责轴(迭代 41 函数级已沿同一条绘制层域轴,本批升到类级);④拆不出内聚单元→停卡呈报;⑤禁沿阈值轴拆。
- 🔴 **禁为机检文本保留无效成员**:禁止为迎合机检消息文本(含计数)保留或新增无效成员/别名;机检键与卡片契约互斥=实现段停卡呈报,不自造第三条路。
- 🔴 **gdstyle 截断缺陷声明**:本卡不依赖任何解析行为——四新文件与两宿主全部平面口径(无内嵌类),实数即闸读数;基线登记 30/19 属截断欠估,禁任何利用截断口径的降数手法(重排成员顺序/挪 setter 位置/删行尾注释),禁把 `_portrait_tex` 这类承重槽位当削减目标凑数。
- 🔴 **潜伏红处置纪律**:T0 一次 ui_input_probe 实跑定谳——确红=已申报的存量红承接,随批修复(T3 四处改址 u.face.*,断言条件与期望值零变化);禁静默放过、禁在实现报告外私记了结。
## 5. 范围边界
做什么:第 3 节两拆件项(单格两域件+宿主上收+board_view 写入面改址;站桩两状态件+宿主转调壳)、潜伏红定谳与四处改址、键账对账收口。
不做什么:迭代 42 在飞范围零触碰(_paint_cell 拆五段、_build_cell_unit、BoardInstaller、商店委托壳);board_hover/breakpoint_store(尾波补件批承接,且其 board_hover 半边待本批合回后施工);main.gd/battle_orchestrator/tune_sim 其余三键(零豁免五键各卡承接);`_portrait_tex` 冗余归一(站桩篇 §9-3 留债册);基线收账(各批合回后用户发令一次人工 `--refresh --force`,本批不刷新基线)。
## 6. 关联文档同步面
| 文档 | 关联点 | 同步义务 |
|---|---|---|
| design/engineering/architecture/architecture.md | 呈现层表 cell_base_layer/cell_mark_overlay 行与 standee_vitals/standee_motion 行(建件后「实现批建件」改现状登记);「gdstyle 计数截断缺陷登记」节的欠估数字(30/33、19/31——收账归后续人工 refresh 批) | 设计权威文档——实现批禁直改;逐条列进 `reports/iter<N>-反哺点-<日期>.md`,用户裁决后归文档批落文 |
| game/tests/README.md | 「棋盘悬停反馈(三语义光标/目标格边框/路径预览点迹)」行——真实入口(ui_input_probe 合成鼠标事件→BoardView._gui_input();读面 hover_probe())与代表用例(ui_input_probe.gd:_ready)预计零变化,批末核对;「地形瓦片套与格面数字可读」「站桩敌人呈现与结算演出落点」「未开格类型微光」「玩家面文案与危险格格面字形」各行代表用例列核对(本批零新增能力、复用既有载体,预计零改动) | 机械面文档——实现批禁写;批末收尾核对表上名字与实际落地一致(改名则回表) |
| design/gdd/ | 无关联文档——结构整改不改游戏规则与玩家可见行为 | 无修订预期;契约句被触碰=停卡呈报走反哺点通道 |
## 7. 文件结构图(卡前)
| 文件 | 新增/修改 | 职责 | 行为属性 |
|---|---|---|---|
| game/presentation/views/cell_base_layer.gd | 新增 | 单格基座层绘制域件:12 成员+九绘制函数逐字搬运+九个 D/E 档常量随迁+公开入口 draw_base | 非行为改动(V1) |
| game/presentation/views/cell_mark_overlay.gd | 新增 | 单格标识与叠加层绘制域件:13 成员+六函数段随迁+draw_centered_text 单点化+两绘制入口 | 非行为改动(V2) |
| game/presentation/views/standee_vitals.gd | 新增 | 站桩身份与命值态件:12 成员+apply_hp(原 _set_hp 整体搬移)+hp_value setter 逐字 | 非行为改动(V3) |
| game/presentation/views/standee_motion.gd | 新增 | 站桩资产与演出态件:11 成员+六迁入函数(两处改形点见 T2) | 非行为改动(V3) |
| game/presentation/views/board_cell_unit.gd | 修改 | 宿主瘦身:类变量 33→10(edge/cell/glow_group 上收+base/face 两实例)、_draw 退六步时序器、雾/glow/记忆态留宿主、头注改写(≤8 行) | 非行为改动(V1/V2) |
| game/presentation/views/board_view.gd | 修改 | 写入面改址约 40 处(u.st.X→u.base./u.face./u.edge/u.glow_group/u.cell,全清单=设计文档单格篇 §5.1/§5.2 对账表;行号 T0 重锚)+cell_rect_probe 一处 | 非行为改动(V1/V2) |
| game/presentation/views/standee_body.gd | 修改 | 宿主改造:类变量 31→10(五冻结 var+st+mo+三计数器)、同名转调壳、tween 路径串改指、源码锚行逐字不动 | 非行为改动(V3) |
| game/probe/ui_input_probe.gd | 修改 | 四处直读改址 u.face.*(T3,:234-235/:243-244/:250/:374-379) | 非行为改动(V4——判据零变化;T0 确红时兼具存量红修复身份) |
零新增数据件、零新增常量表(九常量为迁移非新增)、零新增测试件(全部复用既有断言面)。行为改动核对:本批申报行为改动为零——全部改动为逐字搬运、换参形与读路径改址;判据=零漂移证明(golden 零差异+既有断言面全绿+源码锚逐字)。
## 8. 任务卡 T0..T4
**T0 重锚与潜伏红定谳(0.25–0.5 工作日)**
- [ ] 前置确认:迭代 42 已合回 master(`_paint_cell` 五段在盘)——未合回即停,T0 不开工(编队注记)
- [ ] 以当轮 master 重测六个键账读数(board_cell_unit 33 声明/30 闸账、standee_body 31 声明/19 闸账——截断口径双读数对照)与第 3 节全部 file:line;board_view 写入点按五段新分布逐点重锚(路径形态核对仍为 u.st.X)、漂移处就地改卡并记录;对不上即停卡呈报
- [ ] ui_input_probe 一次实跑定谳潜伏红:红=确证设计文档单格篇 §1.3;绿=证伪设计前提(L3 停机呈报,见第 10 节)——定谳结果记实现报告
- [ ] 复核迁移函数零超标键:`tools/gdstyle_baseline.txt` 无 board_cell_unit/standee_body 任何函数级键(实查确认)——九+六函数与六搬移函数逐字/换参搬运零新键
**T1 单格两域件建件与迁移(1.5–2.5 工作日)**
- [ ] 建 `game/presentation/views/cell_base_layer.gd`:extends RefCounted、无 class_name、`_init(owner: Node2D)`;12 成员+四 setter 体逐字;九函数(_draw_base_layer/_draw_outline_sides/_draw_south_facade/_draw_north_projection/_draw_e_facade/_draw_contact_or_fallback/_draw_contact_bands/_draw_contact_corner/_draw_bevel)逐字搬运,三处机械改写=`st.X`→裸成员名、`draw_X(...)`→`canvas.draw_X(...)`、`st.edge`→`rect.size.x`;公开入口 `draw_base(canvas: CanvasItem, rect: Rect2)`;九常量随迁(FACADE_HIGHLIGHT_PX/FACADE_NEAR_FRAC/FACADE_FAR_FRAC/FACADE_NEAR_COL/FACADE_FAR_COL/PROJECTION_NEAR_COL/PROJECTION_MID_COL/PROJECTION_EDGE_COL/E_FACADE_FRAC——board_cell_unit.gd:12-23,UiKit.E_FACADE_FOOT_COL 不动)
- [ ] 建 `game/presentation/views/cell_mark_overlay.gd`:同形态;13 成员+八 setter 体逐字(含 badge_glyph 的 `_owner._glow_layer` mask 回引);六函数段随迁(_draw_mutation_marks/_draw_glyph_layer/_draw_digit_plate/_draw_glyph/_draw_badge+_draw_overlay_layers 的 dot/hl/removed 三段);公开入口 `draw_marks`/`draw_glyph_layer(canvas, rect, glyph, glyph_color)`(4 参)/`draw_overlay_under`/`draw_removed_dim`/`draw_centered_text(canvas, rect, text, color, font_size)`(5 参,文字渲染单点化)
- [ ] 宿主瘦身:board_cell_unit.gd——`base`/`face` 两实例于 `_init` 自建(preload 常量 `_BASE_LAYER`/`_MARK_OVERLAY`,设计文档 §4.5);edge/cell/glow_group 上收宿主(setter 体改直调自有面:edge 的 glow setup+queue_redraw、glow_group 守卫调 `_sync_glow_layer()`);glyph/glyph_color/plate/fog_state/_glow_layer 原位;`_draw` 改六步时序器(base.draw_base→face.draw_marks→face.draw_glyph_layer→face.draw_overlay_under→`_draw_fog_layer` 原位→face.draw_removed_dim,设计文档 §6 逐字);`_sync_glow_layer`/`_draw_fog_memory` 改址(§5.2——记忆态墨数字改调 face.draw_centered_text,同公式同字号);头注改写(两件句+冻结清单+「hl_color/hl_visible/dot_visible/mutation_mark 探针读 u.face.*」句,≤8 行)
- [ ] board_view 写入面逐点对账改址:按设计文档单格篇 §5.1 对账表每处核对改后形态(T0 重锚行号为准,约 40 处)——u.base.bg_sb/tex_base/outline_sides(assign 保引用语义)/facade_south/proj_band/tex_facade/facade_strip/contact_bands/contact_corners/contact_col/bevel;u.face.badge_glyph/dot_visible/hl_visible/hl_color/tex_seal/treasure_mark/mutation_mark/removed_dim/font/tex_mutation/tex_glyph/tex_badge;u.edge/u.cell/u.glow_group;u.glyph/u.glyph_color/u.plate/u.fog_state 与终写 u.queue_redraw() 不动;cell_rect_probe `u.st.edge`→`u.edge`
- [ ] 孤立验证:`tools/render_gate.sh` golden 三张差异 0.00%(非零即 L3 停机);`--script res://tests/run_all.gd -- --only=player_copy,theme_projection,type_glow,terrain` 全绿;`python tools/run_smoke.py`。probe_gate 各段本卡内暂不计绿——ui_input_probe 段在 T3 改址前处于 T0 已定谳态(存量红或改址等待),T3 闭环
**T2 站桩两状态件建件与迁移(0.5–1 工作日)**
- [ ] 建 `game/presentation/views/standee_vitals.gd`:RefCounted、无 class_name;12 成员(_owner/_kind/_display_name/_enemy_id/_armor/_order/_dead/_hp_max/_hp_cur/hp_value/_hp_tween/_hp_flash_tw);`apply_hp(hp)`=原 `_set_hp` 整体搬移(clamp、重启 `_hp_tween`、tween 写 hp_value——路径串 `"st.hp_value"` 零改);`hp_value` setter 逐字(clamp+`_owner.queue_redraw()`);`_hp_flash_tw` 归此件(flash_hit 回色分支读 `_dead` 同域)
- [ ] 建 `game/presentation/views/standee_motion.gd`:RefCounted、无 class_name;11 成员(_owner/_portrait_sprite/_portrait_tex/_hero_tex/_hero_state/_state_revert_tw/_intent_glyph/_intent_col/_intent_visible/_intent_scale/_glyph_rot);六迁入函数——`set_portrait_texture(tex, flip, box)`(box 由宿主传入)、`register_hero_state`、`apply_hero_state(state, is_hero)`(原 set_hero_state,唯一改形=`st._kind != "hero"` 早退改参判 `is_hero`,三连早退条件序逐字)、`reset_state()`(原 `_revive` 内「置 RESET 强制绕同态早退」两拍封装)、`play_intent_motion(charge)`(`_intent_charge` 改参传入;tween 路径串改 `"mo._intent_scale"`/`"mo._glyph_rot"`)、`state_probe()`
- [ ] 宿主改造:standee_body.gd——`st` 名保留改指 vitals、新增 `mo`;三计数器留宿主(:57-59 原位);同名转调壳(set_portrait_texture/register_hero_state/set_hero_state 三入口 1–2 行转调,签名外形零变);`_draw` 全族与几何函数留宿主、成员前缀改指(st.→mo. 仅资产演出域成员);六个 probe/display_name/enemy_id/is_dead 出口外形零变体内改指(fx_probe 改读宿主计数器);源码锚所在三函数(_draw_hp_bar/_draw_armor_name_line/set_pending)留宿主且 :678-683 锚行逐字不动;`_intent_charge` 与五冻结 var 原位
- [ ] battle_stage_view 写入面对账(站桩篇 §4 清单逐点):结论=零改动——slot_row/box/font 直写原位、三同名转调入口承接、演出三方法原位;hud_presenter :77/:78/:137/:162/:163 零改动;实机核对一遍
- [ ] 孤立验证:`--script res://tests/run_all.gd -- --only=standee_fx_sweep,theme_projection` 全绿;孤立验证同 T1 口径(probe_gate 推迟 T3 闭环)
**T3 潜伏红处置(0.25–0.5 工作日)**
- [ ] ui_input_probe.gd 四处改址::234-235→`u1.face.hl_visible`/`u1.face.hl_color`、:243-244→`.face.hl_color`、:250→`.face.dot_visible`、:374-379→`.face.mutation_mark`——断言条件与期望值零变化,只改读路径
- [ ] 孤立验证(本卡闭环点):`tools/probe_gate.sh --click --full` 全绿——ui_input_probe 恢复绿;若 T0 定谳为红,本步同时即存量红修复闭环;`tools/render_gate.sh` golden 三张复跑一次仍 0.00%
**T4 键账对账与收口(0.5 工作日)**
- [ ] 批末代码域闸全绿(`tools/run_all_gates.sh --code`——三件保险恒跑+本卡申报套件族+探针+渲染+静态)
- [ ] 六文件键账对账:board_cell_unit 10/cell_base_layer 12/cell_mark_overlay 13/standee_body 10/standee_vitals 12/standee_motion 11(平面口径实测);两存量键 30→10、19→10「较登记值只降不升」达成;基线不随批刷新(收账归用户发令人工 refresh)
- [ ] 产出物落位卡:`reports/iter<N>-实现报告-<日期>.md`(各卡状态+潜伏红定谳结论+实现决定记录)与 `reports/iter<N>-反哺点-<日期>.md`(第 6 节所列每条有落点)写齐方算收口
合计约 3–5 工作日。切分预案:T1 超软盒时拆 T1a(基座件+宿主上收)/T1b(叠加件+board_view 改址)各 0.75–1.25 工作日。回归措辞:里程碑步(T 段)出口跑一次全套闸;波内修复只做出红最小单元的最窄确认;新增测试先行孤立验证再并入全套(本批零新增测试)。
## 9. 验证闸——改动—验收对照表
域口径:本批改动全为 `game/` 下非 .md 行为载体——批末跑代码域闸(重闸按域选档);总判据=每行改动以「既有断言面全绿+golden 零差异」证明零行为漂移。**静态键账判据按 test-conventions §8.4 出口在本段申报观测面局限、不入对照表**:S13 六文件键账(10/12/13/10/12/11)与两存量键只降不升(30→10、19→10)以 static_scan S13 回执为判据(可 grep 定位)——键清偿是结构判据非运行期断言,故不出现在下表。
| 行 | 需求点 | 改动(文件:行/行为) | 验收测试(名称+落点+尾缀) | 层级 | 真实入口 | 判据绑定面 | 能力行 |
|---|---|---|---|---|---|---|---|
| V1 | 单格基座层域件 | cell_base_layer.gd 新建(12 成员+九函数+九常量);board_cell_unit.gd 宿主上收 edge/cell/glow_group+六步时序器;board_view.gd 基座域写入点改址(对账表 §5.1 基座行) | render_gate 棋盘 golden 三张(board_L1/L2/L3)+board_shot_probe/type_glow_shot_probe 取证;新增断言零条 | 探针+golden | BoardView.rebuild()→refresh() 真实场景帧(board_shot_probe) | golden 逐像素容差比对(差 ≤16/changed ≤2%)差异 0.00%=绘制命令流逐位;微光子件生命周期取证(glow_group setter 直调时序零漂移) | 既有:地形瓦片套与格面数字可读;既有:未开格类型微光(8 邻作用集/五组色相/零玩法写入) |
| V2 | 单格标识叠加域件+冻结面保留 | cell_mark_overlay.gd 新建(13 成员+六函数段+draw_centered_text);board_cell_unit.gd 四冻结成员原位;board_view.gd 标识域写入点改址+cell_rect_probe 一处 | 复用 player_copy_sweep_test.gd:_sweep_board_glyph+wa8(:138-140 plate/glyph_color 直读零改动);ui_input_probe case④b/⑪/⑮(glyph/fog_state 冻结读面);run_all 02 闸选跑+render_gate golden;新增断言零条 | 单元+探针+golden | BoardView.rebuild()→refresh()(player_copy 夹具真实构建);ui_input_probe 合成鼠标事件 | u.plate/u.glyph_color/u.glyph/u.fog_state 直读断言零改动全绿;golden 三张零差异(雾层原位夹在 hl 与 removed 之间) | 既有:玩家面文案与危险格格面字形;既有:地形瓦片套与格面数字可读 |
| V3 | 站桩两状态件 | standee_vitals.gd/standee_motion.gd 新建;standee_body.gd 宿主 10 成员+转调壳+tween 路径串改指;battle_stage_view 写入面零改动 | 复用 standee_fx_sweep_test 全套(:103 `_intent_charge` 直读、fx_probe().flash_count、enemy_id 解析)+theme_projection_test 三条源码锚(:678-683 逐字)+probe_gate --full 段(fx_probe/ui_probe:碎裂 5/火花 6/闪白计数/三态切换/意图三档/name_line/portrait/has_world_hp_bar/slot_row)+ui_click_probe tooltip;新增断言零条 | 单元+探针 | StandeeBody 公开方法面(set_data/set_hero/set_pending/mark_dead/flash_hit)与 battle_stage_view.on_step_row_fx 演出链;探针场景真实实例化 | fx_probe()/intent_probe()/hero_state_probe() 出口返回逐键;源码锚 contains 断言逐字命中;tween 属性路径串("st.hp_value"/"mo._intent_scale"/"mo._glyph_rot")由意图弹入与三态断言兜底 | 既有:站桩敌人呈现与结算演出落点;既有:UI 全局主题与按钮五态(含对比度锚) |
| V4 | 潜伏红处置与探针改址 | ui_input_probe.gd:234-235/:243-244/:250/:374-379 四处直读改址 u.face.*(判据零变化;T0 确红时兼具存量红修复) | ui_input_probe 全套断言改址后执行且绿(case①②③⑭);probe_gate --click --full 全绿 | 探针 | ui_input_probe 合成鼠标事件→BoardView._gui_input() | 四处断言执行且绿(悬停金框/禁入红框/路径点迹/变异角标,读路径 u.face.*);probe_gate 三硬闸全过=存量红闭环 | 既有:棋盘悬停反馈(三语义光标/目标格边框/路径预览点迹) |
反向核对:diff 中每个改动均有行——本批申报行为改动为零(结构整改,判据=零漂移证明),V1–V4 四行覆盖全部八个文件行。孤儿断言:无(零新增断言)。
## 10. 异常分级
- **L1 自救**:迁移函数编译错、改址漏改、preload 常量名笔误——就地修复重跑最窄确认。
- **L2 记录继续**:实测行号与第 3 节偏离但路径形态一致(T0 重锚记录);探针段实测时长同量级漂移。
- **L3 停机写报告等用户**:①机检预算互斥——新件实数超第 14 节预算或迁移函数现出超标键=上游缺陷停卡退回写卡段;②golden 对拍差异非零(禁换锚禁重制基线);③潜伏红证伪设计前提——T0 实跑 ui_input_probe 现状绿,即设计文档单格篇 §1.3 的 GDScript 取索引语义判断被证伪(改址四处义务不变,等用户裁决后继续);④S13 键恶化或基线外新键;⑤拆分边界纪律④触发(按职责轴拆不出内聚单元);⑥断言面被下游兜底吸收致判据绑不上(test-conventions §8.4 出口呈报)。
## 11. 代拍板白名单
1. 迁移函数与新件头注指址微调(职责语句、冻结清单句与语义不动)。
2. 新件私有 helper 命名微调(职责语义不变;公开入口名按第 8 节逐字)。
3. 改址机械改写(preload 常量顺序、空行排版、注释随迁改写)。
4. 断言失败消息尾缀〔状态件 Vn〕分配与措辞。
5. T0 重锚产生的行号漂移卡面注记更新(不改判据与改后形态)。
## 12. 待裁点
零待裁点,开工门=U0。(裁决记录:2026-10-29 用户裁——单格两文件案〔淘汰整体一件 A3 与成员削减路 B〕;站桩两文件案+三个演出探针计数器留宿主〔淘汰原地 −4 案〕;实例命名 st 沿用/mo;潜伏红随批修复〔弃「先最小工程批改 u.st.* 再二次改址」时序〕;cell 成员保留〔宿主 10 含 cell——弃删除倾向〕;gdstyle 截断口径登记已由 architecture v1.25 落文收口。)
## 13. 落位与可复用性预检
- **cell_base_layer.gd(新增)**:复用面核查——基座层绘制现行全在 board_cell_unit 内嵌类+宿主九函数(全仓唯一实现,无既有件可复用);不能并入 TilePalette(瓦片装载与查表件、架构表明载零绘制面——职责互斥)、不能并入 BoardWorld(世界根/材质挂点)、不能并入 CellUnit 本体的字形迷雾域(变化原因不同)。落点唯一:`game/presentation/views/` 新件,board_cell_unit `_init` 自建持有(每格 Node2D+两 RefCounted,与现状同量级;件内自建不触发 allocation-in-loop 新键——构建器函数体不在循环体内)。交互路径:宿主持有两件引用;件→宿主仅 `_owner.queue_redraw()`/glow mask 回引(与现状 inner class 同形);宿主迷雾记忆态读 `base.tex_base` 公开成员单向(成文于宿主头注)。
- **cell_mark_overlay.gd(新增)**:同上排除;迷雾留宿主是三域中唯一不产生跨件回引的落点(设计文档 §4.4——雾夹在两件入口之间、读件 A 纹理与件 B 字体渲染);`draw_centered_text` 单点化供宿主复用(零复制)。
- **standee_vitals.gd/standee_motion.gd(新增)**:复用面核查——25 成员现行全在 `_StandeeState`(全仓唯一);不能并入 battle_stage_view(壳层视图,站桩本体是世界件)、不能并入 StatusSlotRow(壳层伴随件)。落点唯一:`game/presentation/views/` 新件,standee_body 持有 st/mo;外部仍只经宿主方法与五冻结 var(box/font/slot_row/has_world_hp_bar/_intent_charge 原位),零新增外部直访面;`_owner` 回引同形、禁反向引用。
- **四新件对既有周边件逐一排除**(TilePalette/HeroSprite/CellUnit/BoardWorld,架构文档呈现层表在册件):TilePalette=瓦片装载与查表件、架构表明载零绘制面——四件都不并入;HeroSprite=英雄精灵演出件(落位/位移/帧闪)——与四件变化原因不同;CellUnit 本体(board_cell_unit 宿主)=两格件的持有壳而非合并对象(拆分方向是自宿主出、非并入宿主);BoardWorld=棋盘 Node2D 世界根(材质挂点)——零绘制入参承载。站桩两件另排除 battle_stage_view(壳层视图)与 StatusSlotRow(壳层伴随件)。
- **新增函数清单**:apply_hp/set_portrait_texture(3 参形)/apply_hero_state(is_hero 参形)/reset_state/play_intent_motion(charge 参形)/state_probe/draw_base/draw_marks/draw_glyph_layer/draw_overlay_under/draw_removed_dim/draw_centered_text——全部为既有函数体整体搬移或既有函数换参形与改名入口,无新逻辑。新增前已 grep 同名标识符:`apply_hero_state`/`reset_state`/`state_probe`/`draw_base` 等盘上无第二处。
## 14. 实现规范预算(gdstyle 默认阈值对账)
| 新件 | 公开方法 ≤20 | 类变量 ≤15 | 迁移函数对账 |
|---|---|---|---|
| cell_base_layer.gd | 预算 5(draw_base+4 setter) | 12(设计文档 §4.1 实数) | 九函数逐字搬运——基线无其函数级键(T0 实查)、行数/分支/局部/返回不变=零新键 |
| cell_mark_overlay.gd | 预算 13(5 绘制入口+8 setter) | 13(同上) | 六函数段同上;draw_glyph_layer 4 参、draw_centered_text 5 参(max-parameters 默认 5=合规上限内) |
| standee_vitals.gd | 预算 1(apply_hp)+hp_value setter | 12(设计文档 §5 实数) | apply_hp 整体搬移零键(原 _set_hp 现役无超标键) |
| standee_motion.gd | 预算 6(六迁入函数)+2 属性 setter | 11(同上) | 六搬移函数逐字/换参——最大者 apply_hero_state 4 参数 4 分支全在原值内;宿主转调壳 1–2 行零键 |
存量触面一查:board_cell_unit 键 30→10、standee_body 键 19→10——T0 写明「S13 键较登记值只降不升」预期与达成手段(成员迁出后实数即证);board_view 六键零触碰(改址不动成员数与函数面,32 留债冻结)。宿主 `_init` 一律单参构造注入,防 max-parameters 新键。
## 15. 测试削弱申报
1. ui_input_probe.gd 四处直读改址(T3/V4)——断言条件与期望值零变化,仅读路径 u.X→u.face.X;若 T0 确红,同处兼具存量红修复(恢复断言效力)。
2. 除此之外禁删断言、禁放宽阈值、禁缩小扫描面、禁把真实入口换成下层直调;golden 三张基线禁重制;未申报的削弱由独立验收审计判红。
## 16. 独立验收审计
合并前由未参与实现的会话或子代理执行;报告落 `reports/iter<N>-验收审计-<日期>.md`。审计至少做四件事:逐行核对第 9 节对照表(测试存在、真执行、尾缀可 grep、真实入口未绕过改动点);抽查判据绑定面(golden 零差异在当轮真实跑批成立、源码锚逐字);检查测试削弱(对照第 15 节申报);核对全部行「非行为改动」的零漂移证明。未过不得合并。
## 17. MC/数值与 RNG 零触碰声明
本批零数值改动、零数据表改动、零 RNG 流词表改动;站桩演出与呼吸微光时长全经 UiKit.motion 现值、零漂移。MC 对拍不跑。
@@ -0,0 +1,208 @@
# 需求卡片——战斗编排归约批(battle_orchestrator 类变量 38→15)
> **版本状态**:v1.0 定稿——零待裁点(2026-10-29 用户裁:RoundCycle/BattleFacts 两件形态、encounter 归 BattleFacts、attune 改判、treasure_inventory 改址追认、完美账写口升级可裁量)。
> **接收方**:待办清单条目「战斗域结构深拆批——效果发射端口+宿主瘦身+掷格/受理分件(2026-10-27 登记,来源=批次移交)」——本卡承接其中 battle_orchestrator 瘦身面(architecture 轴丁);该条目的效果发射端口与 reward_economy 分件两子项不在本卡。
> **来源**:`reports/设计-战斗编排类变量归约-2026-10-29.md`(设计讨论段定稿,五待裁点 2026-10-29 用户裁全闭合)。**唯一事实源**:该设计文档全文 + `design/engineering/architecture/architecture.md` v1.25「战斗编排域拆件定稿」节轴丁与「模块归属·功能层」RoundCycle/BattleFacts 两行。
## 1. 目标与完成定义
这批做什么:把战斗结算编排宿主 `game/core/battle_orchestrator.gd` 的 38 个类变量收敛到 15(=gdstyle 阈值,合规)。手段=按变化原因拆两枚新件收编 22 个成员——**RoundCycle**(轮循环驱动件:五段段件持有、段序执行、结算重入门闸、开轮摇号、踩雷计数账)与 **BattleFacts**(战斗事实件:受理事实 encounter、轮 facts 缓冲、封印判定账、装板溯源、条件计数、同调快照;attune 状态两成员随件、行为函数留宿主)——外加两项单点处置:treasure_inventory 注入改址(level_runner 经 RewardGrant 出口直注,原「外部赋值路径零改址」句经用户追认失效)与 _hero_atk 转派生读。
什么状态算完:
1. 宿主类变量实测 15、两新件零 gdstyle 键、battle_orchestrator 全文件零超标键(第 9 节键账)。
2. 游戏行为零变化:同种子完整局步骤流、事件流、两快照载荷逐位一致(第 4 节红线;第 11 节 V0 行)。
3. 批末代码域闸全绿(冒烟+系统测试+单元集成关联档+探针+静态扫描),键账对账完成(第 12 节)。
4. 实现报告与反哺点清单落 `reports/`(T4 产出物落位卡)。
## 2. 设计事实源
- `reports/设计-战斗编排类变量归约-2026-10-29.md`——设计讨论段定稿全文。逐成员去向(38 项五去向)、两新件形态与耦合边界、attune 重裁决、已否决切法、随迁键义务、行为零变化风险点、键账预期、改址盘点,全部以该文档对应节为唯一合同;本卡不复制其表格,T0 逐名对账时引用。
- `design/engineering/architecture/architecture.md` v1.25——「战斗编排域拆件定稿」节轴丁两件(RoundCycle/BattleFacts,跨件单向接线、段类随动、attune 改判、S13 键账收敛义务、验收红线)与「模块归属·功能层」两行、「测试与质量域」S13 豁免第三条注销句——实现照册施工。
- 五待裁点裁决(2026-10-29 用户裁,对应设计文档 §13):①encounter 归战斗事实件=采纳;②treasure_inventory 注入改址=追认(「外部赋值路径零改址」句失效);③attune 重裁决=采纳「状态归 facts、行为留宿主」;④完美账写口升级=采纳(grant_segment 三处直写改经 facts 三方法);⑤PARITY 对拍批准=批内实跑须用户点头、不重锚。
## 3. 现状事实(代码级,2026-10-29 实查;开工 T0 按当轮 master 重测复核)
- `tools/gdstyle_baseline.txt:9-10`——battle_orchestrator.gd 现登记两条类级键:`quality/max-class-variables = 38`、`quality/max-file-length = 1035`;**该文件零函数级键**(59 个函数全部在默认阈值内——设计文档 §7 前提成立,T0 复核)。
- 宿主 38 类变量声明区=`battle_orchestrator.gd:37-85` 与 `:223-227`(逐名清单见设计文档 §2 表)。宿主改后保留 15:db、rng、minesweeper、action_economy、_enemy_system、_status_effects、_reward_economy、_damage、_fx_host、_reward_grant、round_index、battle_result、nest_preview_count、_rounds、_facts。
- **编队前置实态**:迭代 42(gdstyle 尾波清偿批,roadmap 在册)合回后轴丙 BoardInstaller 已建——`_board_generator` 成员随件退役(38→37)、装板域六函数迁出、宿主复位块留薄壳 `_install_and_reset`、文件长键归绿;届时宿主约 890 行/37 成员,本卡叠加其上。**本卡在迭代 42 合回之前禁开工**;T0 按当轮 master 重测对账。
- 段驱动现态:五段构造 `battle_orchestrator.gd:256-260`(授予/战斗两段三引用形,aura/decay/verdict 单引用形);三闸 `_maybe_settle` :592-597;段序体 `_settle` :602-613(终局早退不回置 _settling);开轮摇号 `_roll_round_actions` :677-721(behavior_roll 流 :717,mines_hits 转存 :720-721);`_on_round_end` 末行 :589 调 `_maybe_settle`。
- 事实族写读点:缓冲追加 `_on_cell_revealed` :554-580(身份快照捕获 :576 留宿主);`_on_seal_judged` :583;`_facts_path` 写 `_on_round_end` :588;轮复位 `_reset_round_facts` :976-979(三调用点 :273/:810/:862);封印/完美/标错/板序/溯源清零在装板复位块 :442-446(迭代 42 后归宿主薄壳);`_refresh_used_this_round` 复位点 `_exit_distribution` :811;完美谓词 `perfect_sweep_earned` :1033-1035。
- treasure_inventory:宿主声明+setter 转发块 `battle_orchestrator.gd:48-52`;唯一外部注入点 `level_runner.gd:520`;宿主读 :111/:203/:450/:858;`grant_segment.gd:370-371` 读 `oc.treasure_inventory`。
- _hero_atk:声明 `battle_orchestrator.gd:227`、受理写入 :304、spawn 消费 :305、`combat_segment.gd:56` 消费 `oc._hero_atk`。
- attune 外部三面(零改址标的):`attune_has` 公有面消费=table_structure_guard_test 起战断言(:162/:166)与 breakpoint_resume_test;`attune_param_sum`=main.gd:567 与 treasure_effects_test;`attune_convert_state`=treasure_interact_controller.gd:125。三面全部留宿主公有面。
- 冻结面:`nest_preview_count` 外部直读=main.gd:536-537+treasure_effects_test:153;`round_index` 公有直读=system_test.gd:447-462(st.round_index)等四套件约 15 处。
- **设计文档 §11 漏列一处(T0 实查补入)**:`settle_segments_test.gd:27` 接线断言 `oc._grant_seg != null and oc._grant_seg.oc == oc`——段件迁 RoundCycle 后必红,须改指 `oc._rounds._grant_seg`。
- `tools/run_all_gates.sh` PARITY_TOUCH_FACES(:161 定义区)含 `game/core/battle_orchestrator.gd`——本批必触面。
- `game/tests/static_scan.sh`——S8 await 文件集(:317,9 文件)与 S7 B1 域文件集(:359,9 文件)均未含两新件路径;round_cycle.gd 经 oc 调 B2 符号(`_enemy_system` 族)须随批增行,battle_facts.gd 零协作调用不入清单。
## 4. 设计契约(违反即返工的红线条款)
- 🔴 **行为零变化(本批总判据)**:同种子下事件流/步骤流/两快照载荷/存档往返逐位一致;玩家可见面零变化;`design/gdd/systems/` 零修订预期。
- 🔴 **RNG 取号序零漂移(封闭流随件迁移先例句)**:behavior_roll 随 `roll_round_actions` 迁 RoundCycle——流名、开流时点、取号序逐字(先例句=「fx_reveal 封闭流随件迁移取号序不变」同款);encounter/gp_drop/board_gen/variant_place/fx_reveal 五流留原地零触碰;零 `randomize()`/自建随机。
- 🔴 **信号顺序契约冻结**:五信号(step_row/battle_finished/round_started/board_changed/settlement_snapshot)留宿主;发射语句零迁移、发射时序零变化;A2 三 connect(:251-254)逐字。
- 🔴 **两快照出口签名与载荷逐字不变**:presentation_snapshot/diagnostic_snapshot 字段名、嵌套结构、值口径逐字——内部读数改指两件投影后值恒等(round_index/attune_safe_seen/完美三账/hero_atk 派生读均受理后不变量)。
- 🔴 **明细行协议词表零触碰**:基础 9 类+扩展行词表、SOURCE_EXEMPT_TYPES/SOURCE_EXEMPT_CLASSES 两常量、`_emit_row`/`_assert_row_source` 行发射基建留宿主零迁移。
- 🔴 **PARITY 触面**:battle_orchestrator.gd 触 PARITY_TOUCH_FACES——实跑对拍须经用户批准、不得借机重锚。
- 🔴 **拆分边界纪律**(判据权威=code-conventions §1.1,此处立卡内执行条款):①每个拆出单元须有可陈述的职责语句与单一变化原因(实现报告逐件一行承载);②拆出单元须有集体身份——命不出名字、只能说「剩下的成员」的打包=凑计数袋,禁;③「过阈值」只许作为发现信号,作为拆分或收拢的动机即违规;④按纪律拆不出内聚单元 → 停卡呈报走豁免/还债通道,禁硬拆凑绿;⑤拆分沿职责轴不沿阈值轴。两新件职责语句见第 8 节(RoundCycle=轮结算周期的推进结构;BattleFacts=战斗事实的记录与查询口径)。
- 🔴 **禁为机检文本保留无效成员**:22 成员随件迁出+treasure_inventory/_hero_atk 两成员退役=宿主删 24 项(37−22−2+RoundCycle/BattleFacts 两新件接线引用=宿主 15,账平——grilling 复核订正原算术),禁保留别名、别名转发属性或空壳;机检键与卡片契约互斥时,实现段一律停卡呈报,不得自造第三条路。
- 🔴 **随迁键收敛义务**:迁移函数逐字纪律——`roll_round_actions`(45 行/分支≈8 贴线)、`settle_if_due`、`reset_round`、三 mark 方法迁移与改指**禁顺手增分支/局部**;函数迁入新文件若出超标键=卡内同步收敛(拆助手函数,拆分不改语义;先例=迭代 40 卡① 12 随迁键收敛),禁带新键进批末闸。
- 🔴 **段类接线改形守 Middle Man 禁壳**:段类对宿主的直调形态不变(段类经宿主引用直调,现状形态);段内改指一律调用点改指(`oc._X` → `oc._facts.X`/`reward_grant.treasure_inventory`),宿主与新件禁留转发壳。
- 🔴 **_fatal 与 battle_result 状态机唯一写点留宿主**:RoundCycle/段类经 oc 直调 fatal 面零改形;BoardInstaller(迭代 42 建件)fatal Callable 零触碰。
- 🔴 **BattleFacts 成员冻结**:15/15 贴顶——实现期禁增员,增员即停卡;扩容阀=下一张要加事实成员的卡先把封印判定账五成员二次拆出(SealLedger,−5)再落新账,禁硬挤。
- 🔴 **reset_round 复位边界**:只清 reveals/seals/path 三项、**不碰 refresh_used**——_battle_over 后快照读到的 refresh_used 必须保持末轮值(设计文档 §8.5 险点,对照表 V2 行断言钉住)。
## 5. 范围边界
做什么:设计文档 §2 逐成员去向表的全部迁移与改址、两新件建件、treasure_inventory 改址、_hero_atk 派生读、随迁键收敛、S7/S8 静态扫描随动、对照表新增断言四条。
不做什么:
- 轴丙 BoardInstaller 建件——迭代 42 在册卡执行,本卡前置、不重复。
- 五段段类职责与段序语义零改写(只改指);`_exit_distribution` 留宿主(设计文档 §6.5 已否决迁驱动件——判定段直调宿主,零新引用环)。
- attune 行为函数留宿主(attune_has/attune_param_sum/attune_convert_state/积点自动兑付体/充能重置零迁——设计文档 §5 重裁决);AttuneLoadout 零触碰。
- nest_preview_count 冻结面、round_index 公有直读面、A2 三事件订阅面——零变化。
- 数值表、RNG 流词表、信号载荷 schema、明细行词表——零触碰;本批零数值改动,MC 零跑(第 13 节)。
- `game/tests/README.md`、`design/` 全目录、根规则文件——实现批禁写(反哺点通道,第 6 节)。
- 效果发射端口定形与 reward_economy 分件——归接收方条目其余子项,另行设计讨论。
## 6. 关联文档同步面
| 文档 | 关联点(本批实现会改变它的哪条陈述) | 同步义务 |
|---|---|---|
| design/engineering/architecture/architecture.md | 轴丁两行与功能层 RoundCycle/BattleFacts 行——设计已闭合落文 v1.25,实现照册施工;「测试与质量域」S13 豁免第三条注销句已预写注销(本批键账达成即生效,未达成=停卡非落文);两行「构造=引用束注入」句与本卡三参直构/零参直构实态的口径差;批末成员数/行数/公开方法数实测值与在册数字出入 | 设计权威文档——实现批禁直改;出入逐条列进 `reports/iter<N>-反哺点-<日期>.md`,用户裁决后归文档批落文 |
| game/tests/README.md | 本批零新增能力、零入口与代表用例名变更(测试改指只动成员寻址;新增断言四条全部内嵌既有函数);能力清单零增删改 | 机械面文档——实现批禁写;批末收尾核对表上名字与实际落地一致(改名则回表) |
| design/gdd/systems/(全树) | 无关联文档——结构整改不改游戏规则与玩家可见行为 | 无修订预期;若实现中发现契约句被触碰,停卡呈报走反哺点通道 |
## 7. 卡前文件结构图
| 文件 | 职责 | 改动性质 |
|---|---|---|
| game/core/battle_facts.gd | 战斗事实件(新增,architecture v1.25 功能层在册)——受理事实/轮 facts 缓冲/封印判定账/溯源/条件计数/同调快照,自带轮复位与完美账写口 | 新增(非行为改动——成员迁移;验收=对照表 V1/V2/V6 行) |
| game/core/settlement/round_cycle.gd | 轮循环驱动件(新增,同在册)——五段段件持有与段序执行、结算重入门闸、开轮摇号、踩雷计数账 | 新增(非行为改动;验收=V1/V3 行) |
| game/core/battle_orchestrator.gd | 战斗结算编排中枢——宿主 15 成员定着、行发射基建、状态机、两快照出口、attune 行为读数与触发面 | 修改(非行为改动——成员改指、三函数迁出、派生读、注入改址;验收=V0–V5 行) |
| game/core/settlement/grant_segment.gd | 授予段——事实族改指约 23 处+完美三处直写改经三 mark 方法 | 修改(非行为改动) |
| game/core/settlement/combat_segment.gd | 战斗段——2 处改指(oc._facts_reveals 扫描、oc._hero_atk 派生调) | 修改(非行为改动) |
| game/core/level_runner.gd | 关卡域生命周期——库存注入 1 行改经 `reward_grant()` 出口直注 | 修改(非行为改动——注入路径改址,注入时序与消费面零变化;验收=V5) |
| game/tests/static_scan.sh | 静态扫描域承载——S7 B1 域文件集与 S8 await 文件集增行 round_cycle.gd | 修改(工程随动,architecture 拆件定稿节 S7/S8 随动条在册) |
| game/tests/unit/battle_settlement/seal_polarity_test.gd · unit/core/feat_vouchers_test.gd · unit/battle_settlement/trigger_cond_test.gd · unit/battle_settlement/round_flow_skill_pool_test.gd · unit/core/settle_segments_test.gd · unit/core/treasure_effects_test.gd · unit/core/adventure_feats_test.gd · unit/core/meta_progression_forge_test.gd · unit/battle_settlement/roll_multiplier_test.gd | 成员寻址改指(断言条件与期望值零变化)+新增断言内嵌既有函数(V1/V2/V4/V5) | 修改(改指=非行为改动;新增断言行=对照表对应行) |
aura/decay/verdict 三段、battle_fx_host、reward_grant、damage_controller、main.gd、treasure_interact_controller、board_installer——零改动(设计文档 §11 盘点)。新增件「为什么不能复用」理由与唯一落点核查见第 8 节;对不上即卡片不成立。
## 8. 落位与可复用性预检
- **battle_facts.gd(新增)**:复用面核查——战斗事实记录面现行只摊在 battle_orchestrator 成员区(全仓 grep 同名与同义标识符:`_facts_reveals`/`_seal_consumed`/`_perfect_*` 等无第二实现),无既有件可复用。不能并入 BattleFxHost(效果引擎宿主域——变化原因是效果发射与施加,不是事实记录)、不能并入 RewardGrant(授予管线域——事实账不是授予物)、不能并入五段段类(段类只搬运时序零持有账——缓冲写读跨段跨界,归宿主编排面)、不能并入 AttuneLoadout(营地/冒险域充能物化单源,迭代 39 已闭合契约——重开已闭合边界=设计文档 §5 理由 4 否决)。落点唯一:`game/core/battle_facts.gd`。分层:core 层 RefCounted,零注入引用、零信号、零协作对象调用——纯数据+谓词+写口;身份快照捕获(query_full_snapshot)留宿主 `_on_cell_revealed`,防它变成第二编排面。
- **round_cycle.gd(新增)**:复用面核查——轮结算周期推进机构(段件持有/重入闸/摇号/踩雷账)现行只存在于宿主三函数+五成员,无第二实现。不能并入 BattleFxHost/RewardGrant(变化原因不同,同上)、不能并入任一段类(它是段件的序主人——持段件者不能是被持者)。落点唯一:`game/core/settlement/round_cycle.gd`(与五段段件同目录)。分层:core 层 RefCounted、零 await;随机只经 `oc.rng` 的 behavior_roll 封闭流。
- **引用束注入构成**:引用束先例(BattleFxHost/RewardGrant 的字典束)防的是 `_init` max-parameters 新键——本批两新件参数均未触发:RoundCycle `_init(host, fx_host, reward_grant)` 三参直构(fx_host/reward_grant 仅作段构造透传,不落成员);BattleFacts 零参直构。architecture 两行「构造=引用束注入」句按设计文档 §3/§4 实态执行(三参直构无需束),出入随反哺点申报。
- **依赖方向**:宿主→两新件单向(宿主 `_init` 建件并接线,每战新建同灭);RoundCycle 持 `oc`=五段段类既定同款形态(段类已持宿主引用直调——非新增反向引用),除 `oc` 外禁持宿主其他成员、禁回调宿主私有族;BattleFacts 不持任何对象引用——宿主与段类经注入引用直读写(fx_host._fx_bonus_delta 跨件直读写同款现状形态)。新件之间零互引。
- **新增函数**:宿主 `_hero_atk()` 派生读=`_journal()`「读面即引用、无第二账」同款先例(encounter 受理后只读,派生值恒等);`reset_round`=原 `_reset_round_facts` 逐字;三 mark 方法=新写口(升级采纳案)。零新增数据件、零新增常量表。
## 9. 实现规范预算(新件对照 gdstyle 默认阈值;写码前对账,超预算面=停卡退回写卡段)
| 新件 | 公开方法 ≤20 | 类变量 ≤15 | 迁移函数对账(基线源函数键) |
|---|---|---|---|
| battle_facts.gd | 预算 4(reset_round+mark 三方法;设计文档 §10 表载 5 属含 `_init` 宽口径计数差,两口径均 ≤20 零键风险) | 15(贴顶——实现期禁增员,增员即停卡;扩容阀=SealLedger 二次拆出) | `reset_round`=原 `_reset_round_facts` 逐字(基线无其函数级键);三 mark 新增小函数远在阈值内 |
| round_cycle.gd | 预算 3(settle_if_due/roll_round_actions/is_settling) | 8(oc+五段段件+_settling+mines_hits) | `settle_if_due`=`_maybe_settle`+`_settle` 合体(两源函数基线零键;闸序与段序逐字);`roll_round_actions` 45 行/分支≈8 贴线——迁移禁增分支/局部,确需增条件即停手核对 gdstyle;`is_settling` 新增小函数 |
存量触面一查:battle_orchestrator 类变量 37(轴丙后实测)→15 只降、文件长约 890→约 830 只降(均阈值内,S13 键较登记值只降不升——达成手段=本卡迁移,无豁免申报);grant_segment/combat_segment 改指零新增键(`_judge_seal` 等函数体只换成员寻址);level_runner 改 1 行零新增键。两新件与改址后宿主、段类落地后先跑 `python tools/gdstyle_gate.py` 预检一次再进批末闸(T4 步骤)。`_init` 形态:RoundCycle 三参/BattleFacts 零参(max-parameters 阈值 5 未触发)。新增文件全类型标注(S9——容器参数化走 `Dictionary[Variant, Variant]` 现行口径);头注按 code-conventions §1.4.1(职责语句+封闭面声明,禁变更叙事、禁文档反链)。
## 10. 任务卡 T0..T4(估时为区间;工作量限制只属迭代层)
**T0 重测对账(0.25–0.5 工作日)**(前置:迭代 42 合回——BoardInstaller 在库;产出:逐成员对账结论与改址点名清单,后续各卡取用)
- [ ] 以当轮 master 重测 battle_orchestrator.gd 类变量逐名清单,对账设计文档 §2 表五去向(留宿主/RoundCycle/BattleFacts/退役改址/派生读;轴丙后实态 37 项,`_board_generator` 行应已消失)——对不上即停卡呈报
- [ ] 复核 gdstyle 基线:battle_orchestrator 函数级键数(预期零——漂移即停卡呈报);类变量键现值与文件长键现状(应已随轴丙归绿或基线已 refresh)
- [ ] 复核第 3/7/9 节全部 file:line 引用与设计文档 §11 改址盘点实数(grant_segment 约 23–25 处、测试各套件逐处点名——含 settle_segments_test:27 补入项);漂移处就地改卡并记录
**T1 BattleFacts 建件与事实成员迁移(0.75–1 工作日)**(取用:T0 对账清单;产出:`_facts` 在座、事实族 15 成员归件——T2/T3 引用其成员名)
- [ ] 建 `game/core/battle_facts.gd`:class_name BattleFacts,extends RefCounted;15 类变量初值逐字承原宿主声明(encounter/reveals/seals/path/refresh_used/board_seq/board_from_midround/seal_consumed/seal_miss_seen/perfect_hit_true/perfect_hit_false/perfect_forgiven/feat_first_dig_used/attunement/attune_safe_seen);公开方法 4:`reset_round()`(原 `_reset_round_facts` 逐字——只清 reveals/seals/path 三项,不碰 refresh_used)、`mark_perfect_hit()`、`mark_perfect_miss()`、`mark_perfect_forgiven()`;头注写职责语句+成员封闭面+零注入零信号零协作调用
- [ ] 宿主 `_init` 建 `_facts = BattleFacts.new()`;事实族成员全量改指:宿主声明删 15 项、读写点改 `_facts.X`(encounter 全部读点——_journal/_attune_loadout/_fx_host_fact/受理段/fx_state/两快照/gp_drop,按 T0 点名清单逐处;缓冲追加/复位/装板清零/perfect 谓词同批);`_reset_round_facts` 函数删除,三调用点改调 `_facts.reset_round()`(时序位置逐字)
- [ ] grant_segment 事实族改指(`oc._facts_reveals/_facts_seals/_facts_path/_seal_consumed/_seal_miss_seen/_feat_first_dig_used/_perfect_*` → `oc._facts.X`);完美三处直写改经三 mark 方法(:311/:379/:394——写口升级采纳案;:397 forgiven 读数直读 `_facts.perfect_forgiven` 零变化)
- [ ] 测试改指:seal_polarity_test 8 处(_perfect 直写→_facts.perfect_*)、feat_vouchers_test facts 族、treasure_effects_test:309(ob14.attunement→ob14._facts.attunement)、adventure_feats_test 1 处(encounter 读→_facts.encounter)——断言条件与期望值零变化
- [ ] 新增断言 round_flow_skill_pool_test.gd:_smoke_full_battle 内嵌〔编排归约 V2〕:终局后 `presentation_snapshot()["refresh_used"]` 等于末轮结算 snapshot 的 economy.refresh_used(复位边界险点,规格见对照表)
- [ ] 孤立验证:`godot --headless --script res://tests/run_all.gd -- --only=seal_polarity,feat_vouchers,treasure_effects,adventure_feats,table_structure_guard,round_flow_skill_pool,variant_placement` 全绿+`python tools/run_smoke.py`(出红只跑红件最小单元)
**T2 RoundCycle 建件与段驱动迁移(0.75–1 工作日)**(取用:T1 的 `_facts`;产出:`_rounds` 在座、段驱动三入口——T3 引用其方法名)
- [ ] 建 `game/core/settlement/round_cycle.gd`:class_name RoundCycle,extends RefCounted;类变量 8(oc/mines_hits 公有+_grant_seg/_aura_seg/_combat_seg/_decay_seg/_verdict_seg/_settling 私有);`_init(host, fx_host_ref, reward_grant_ref)` 三参——五段构造五行从宿主 `_init` 逐字搬入(构造参数与持有形态不变);公开方法 3:`settle_if_due()`(原 `_maybe_settle` 三闸+`_settle` 段序体合体——闸序 settling→battle_result→phase 逐字,终局早退不回置 _settling)、`roll_round_actions()`(原函数逐字迁入——behavior_roll 流名/开流时点/取号序逐字,宿主引用经 oc 改指,禁增分支/局部)、`is_settling()`;头注写职责语句与单一变化原因
- [ ] 宿主 `_init`:五段构造五行迁出,改 `_rounds = RoundCycle.new(self, _fx_host, _reward_grant)`(置于两件建齐与 bind 接线之后——构造序禁环不变);五段成员声明删除;`_maybe_settle`/`_settle`/`_roll_round_actions` 三函数删除
- [ ] 宿主调用点改址:`_on_round_end` 末行→`_rounds.settle_if_due()`;begin_battle 与 `_exit_distribution` 的 `_roll_round_actions()`→`_rounds.roll_round_actions()`;diagnostic_snapshot settling 读→`_rounds.is_settling()`;`_begin_battle_fx_state` 踩雷清零→`_rounds.mines_hits = {"total": 0, "last": 0, "round": 0}`(赋值复位——语句时点逐字);`_book_negative_blast` 两写→`_rounds.mines_hits`
- [ ] 测试改指:trigger_cond_test :119/:126/:131(orch._mines_hits→orch._rounds.mines_hits);settle_segments_test :27(→oc._rounds._grant_seg);round_flow_skill_pool_test:1022 与 feat_vouchers_test 5 处(_grant_seg→_rounds._grant_seg)
- [ ] 新增断言 settle_segments_test.gd(接线检查段内嵌)〔编排归约 V1〕:oc._rounds 非空且 `_rounds.oc == oc`、五段段件齐在 _rounds、oc._facts 非空(规格见对照表)
- [ ] `game/tests/static_scan.sh` S8_FILES(:317)与 S7_B1_SET(:359)增行 `game/core/settlement/round_cycle.gd`(battle_facts.gd 零协作调用不入两清单)
- [ ] 孤立验证:`-- --only=round_flow_skill_pool,settle_segments,trigger_cond,seal_polarity,skill_unlock,roll_multiplier,variant_placement` 全绿+冒烟
**T3 宿主改形收束(0.5–0.75 工作日)**(取用:T1/T2 两件与成员名;产出:宿主 15 成员定着)
- [ ] 宿主 `_rounds`/`_facts` 成员声明落位;已迁成员声明复核清零——类变量实测 15(第 3 节名单),禁无效成员
- [ ] treasure_inventory 改址:宿主成员与 setter 转发块(:48-52)删除;四处读改指 `_reward_grant.treasure_inventory`(_hook_attune_consume/_reseed_attune_charges/装板薄壳叠加层退役/_battle_over 叠加层退役);`level_runner.gd:520` 改 `_settlement.reward_grant().treasure_inventory = treasure_inventory`(注入时序在宿主构造之后不变)
- [ ] _hero_atk 派生读:宿主新增私有函数 `_hero_atk() -> int`(返回 `int(_facts.encounter.get("hero_atk", int(db.combat.hero.atk)))`);受理段写入与 spawn override 改调;`combat_segment.gd:56` oc._hero_atk→oc._hero_atk();_hero_atk 成员删除
- [ ] attune 读数出口核验:attune_has/attune_param_sum/attune_convert_state/_attune_charge_safe_row/_attune_safe_seen_read 读源改 `_facts.attunement`/`_facts.attune_safe_seen`——三个外部消费面(main.gd:567、treasure_interact_controller.gd:125、table_structure_guard_test/breakpoint_resume_test 起战断言)零改址零触碰
- [ ] 新增断言 roll_multiplier_test〔编排归约 V4〕与 treasure_effects_test〔编排归约 V5〕(规格见对照表)
- [ ] 孤立验证:`-- --only=roll_multiplier,treasure_effects,breakpoint_resume,level_shop_economy,round_flow_skill_pool` 全绿+`python tools/run_system_test.py`
**T4 键账对账与收口(0.25–0.5 工作日)**(取用:T0–T3 全部产出;产出:本批交付物)
- [ ] `python tools/gdstyle_gate.py` 预检一次——宿主类变量 15、round_cycle 8、battle_facts 15、文件长 ≤1000(预期约 830)、零基线外新键;出超标键→按第 4 节随迁键收敛义务卡内拆助手后复检
- [ ] 里程碑步出口跑全套闸:`bash tools/run_all_gates.sh --code` 全绿(改动全为代码面);闸 11 PARITY 触面按第 4 节条款——实跑对拍须用户批准发起、不得借机重锚,NEED-APPROVAL 时停步呈用户裁决
- [ ] 键账对账:第 9 节预期逐键核;基线 refresh 由用户发令人工 `python tools/gdstyle_gate.py --refresh`(须 --force——全基线 16 键消失 ≥2 条触发骤降守卫;与姊妹卡同批编队时一次 refresh 合并执行)
- [ ] 产出物落位卡:`reports/iter<N>-实现报告-<日期>.md`(各卡状态+实机目检总清单+实现决定记录+逐拆出单元职责语句一行)与 `reports/iter<N>-反哺点-<日期>.md`(第 6 节同步面逐条落点)写齐方算收口
合计估时约 2.5–3.75 工作日(设计文档 §12 载 2–3 日;上探余量=测试改址逐处点名与 PARITY 批跑配合;PARITY 实跑须用户在场批准,不占卡估时)。切分预案:T1/T2 迁移函数出超标键需卡内拆助手时,超软盒预挂改由 T3 并 T4 吸收。
## 11. 验证闸——改动—验收对照表
域口径:本批改动全为 `game/` 下非 .md 行为载体——批末跑代码域闸(`tools/run_all_gates.sh --code`);里程碑步(T 段)出口跑一次全套闸,波内修复只做出红最小单元的最窄确认,新增测试先行孤立验证再并入全套。测试执行两入口铁规不破。三件保险(冒烟/系统测试/静态扫描)恒跑;02 单元与集成按关联档选套件(上表落点套件并集)。能力清单:本批零新增能力、零入口与代表用例名变更——能力行全部为既有名,零增删改(第 6 节)。**静态判据申报(不入对照表)**:键账收敛与静态随动(宿主 38→15、round_cycle 8/battle_facts 15、零基线外新键、static_scan.sh S7/S8 两清单增行)无运行时可观测提交面——判据=`python tools/gdstyle_gate.py` 与 `game/tests/static_scan.sh` 退出码(T4 执行),属静态判据+评审注记申报观测面局限(test-conventions §8.4 出口)。
| 行 | 需求点 | 改动(文件:行/行为) | 验收测试(名称+落点+尾缀) | 层级 | 真实入口 | 判据绑定面 | 能力行 |
|---|---|---|---|---|---|---|---|
| V0 | 行为零变化(本批总判据) | 全部结构改动(第 7 节清单) | PARITY 同种子完整局对拍(`tools/parity_anchor.py`,用户批准后实跑、禁重锚);关联套件零改址应绿 | 集成+对拍 | 真实局 begin_battle→挖掘→结算→终局 | step_row/settlement_snapshot 逐位一致——差异非零即停机呈报 | 既有:回放确定性(同种子三变体逐位) |
| V1 | 两新件建件接线(T1/T2) | battle_facts.gd/round_cycle.gd 新建;宿主 _init 建件接线;五段构造迁 round_cycle | 新增 settle_segments_test.gd 接线检查段内嵌〔编排归约 V1〕:`oc._rounds` 非空且 `_rounds.oc == oc`;五段段件齐在 `_rounds`;`oc._facts` 非空 | 单元 | BattleOrchestrator 直构(settle_segments_test 现行夹具同款) | 编排器接线面(新件在座与宿主回指——接线断言本体) | 既有:轮内流与结算五段全序 |
| V2 | reset_round 复位边界(险点) | battle_facts.reset_round 只清三缓冲;宿主三调用点改调 | 新增 round_flow_skill_pool_test.gd:_smoke_full_battle 内嵌〔编排归约 V2〕:终局后 `presentation_snapshot()["refresh_used"]` == 末轮结算 snapshot `economy.refresh_used` | 单元 | begin_battle→轮内刷新→停手→结算→终局 | 两快照同键值恒等(复位不碰 refresh_used 的可观测提交面) | 既有:轮内流与结算五段全序;既有:停手转存储备与轮内刷新(上限/AP 不重置/刷新图零清图奖励) |
| V3 | 段驱动与摇号迁移(重入门闸/settle_if_due/roll_round_actions/mines_hits 账) | 三函数迁出宿主;宿主调用点改址;trigger_cond_test 3 处改指 | 复用 round_flow_skill_pool_test 全套(_smoke_full_battle/_smoke_settlement_segments/_smoke_skill_pool_replay_independence)、settle_segments_test V4-3 真实一轮、skill_unlock_test、trigger_cond_test(改指后应绿)——零新增断言 | 单元 | begin_battle;stop→WAITING→settle_if_due | 五段裁定行序+settling 闸+终局早退+同种子摇定逐位(behavior_roll 流随件零漂移由既有回放断言钉住)+mines_hits 转存读数 | 既有:轮内流与结算五段全序;既有:技能池数据面与回放独立;既有:Boss 半血解锁技门控 |
| V4 | _hero_atk 派生读 | 成员删→私有函数;combat_segment.gd:56 改调 | 新增 roll_multiplier_test.gd(既有主角攻击链函数内嵌)〔编排归约 V4〕:enc 携 `hero_atk` override 起战→主角攻击单 base_value==override;缺省→base_value==hero 表值 | 单元 | begin_battle(enc)→战斗段主角先手 | 主角攻击单基值(受理后派生值恒等的判据本体) | 既有:伤害公式与掷点乘区 |
| V5 | treasure_inventory 注入改址 | level_runner.gd:520 改经 reward_grant() 出口;宿主四处读改指;宿主 setter 转发块删 | 新增 treasure_effects_test.gd(秘宝使用链内嵌)〔编排归约 V5〕:注入后 `current_battle().reward_grant().treasure_inventory` 与关卡库存同一引用,且 use_treasure 受理走通 | 单元 | LevelRunner 建战注入→use_treasure 四步 | 注入引用同一性+受理面走通(改址后消费面不断链) | 既有:秘宝结构冻结与 12 件效果 |
| V6 | 封印判定账/装板溯源/受理事实迁移(完美写口升级、attune 状态随件) | 事实族改指(grant_segment 约 23 处+测试);三 mark 写口;attune 读源改 _facts | 复用 seal_polarity_test 全套、feat_vouchers_test(契约 2 计数纯净 R2)、variant_placement_test、meta_progression_forge_test、adventure_feats_test、table_structure_guard_test(attune 面零改址应绿——本批最硬的外部面零变化证)——零新增断言 | 单元 | 封印动作→结算;begin/refresh/exit 装板;begin_battle(enc) | 完美三账读数+去重闸+契约 2 计数纯净;刷新图零清图奖励+board_seq;enc 携带键贯通;attune_has/param_sum/convert_state 外部面零变化 | 既有:封印与极性路由/不可逆;既有:清图奖励双份与零路径;既有:变异布置门控;既有:专长(奇物)授予与凭证保底;既有:元进度入账与锻造两轴;既有:装板与开局免费展开(封锁格无资源、计入清图) |
反向核对:diff 中每个行为载体改动均有行——本批申报**行为改动零条**(全部为非行为改动:成员迁移与调用点改指,判断依据=V0 同种子逐位一致证明+既有断言面零改址应绿;完美写口升级=同一时点同一增量改经方法单点,语义逐字)。新增断言四条(V1/V2/V4/V5)全部挂行;孤儿断言零条。测试削弱申报见第 15 节。
## 12. 基线纪律(S13 键账)
1. 本卡键账目标=battle_orchestrator 类变量键归绿(实测 15 后随 refresh 消失);文件长键已由轴丙(迭代 42)归绿,本卡保持文件长 ≤1000(预期约 830)。
2. 禁为过闸 refresh 换绿:基线重生成只由用户发令,批末键账对账后人工 `python tools/gdstyle_gate.py --refresh` 一次执行(禁闸内自动重生成、禁实现批中途 refresh)。
3. 重锚守卫:新基线键数较旧基线少逾 10% 须 `--force` 显式确认——本批与轴丙预期合计消失 ≥2 条(16 键基线),须带 `--force` 由用户执行。
4. 还债=数值下降自然绿:迁移后同键数值下降不判红;出现恶化(同键数值较登记值上升、基线外新键)=停卡呈报,禁自行消化。
5. S13 豁免第三条(battle_orchestrator max-class-variables,architecture v1.25 已预写注销句)随本批达成生效——未达成=停卡呈报,非落文事项。
## 13. MC/数值与 RNG 零触碰声明
本批零数值改动、零数据表改动、零 RNG 流词表改动、零玩法字面量引入——结构整改不改数值与 RNG 消费序。behavior_roll 封闭流随件迁移取号序不变(流名、开流时点、取号序逐字)。数值与 RNG 零触碰则 MC 零跑;battle_orchestrator.gd 触 PARITY_TOUCH_FACES——实跑对拍须经用户批准、不得借机重锚(批末闸 11 判 NEED-APPROVAL 时由用户裁决:批准实跑或裁跳过,卡内不定案)。
## 14. 异常分级
- **L1 自救**:改指漏改编译错、测试寻址漏改——就地修复重跑最窄确认。
- **L2 记录继续**:实测行数/改指处数与设计文档「约」值区间偏离、头注指址微调——记入实现报告「实现决定记录」。
- **L3 停机写报告等用户**:①机检预算互斥——两新件实数超第 9 节预算、BattleFacts 需增员、或迁移函数现出超标键=上游缺陷停卡退回写卡段(禁自造第三条路);②encounter 归属被实现期证伪——受理事实与轮 facts 复位节奏冲突实锤、且设计文档 §6.3 两条砍路均破冻结面(宿主 16 不可达)=停卡呈报走判据④通道;③T0 对账不符(成员去向对不上、基线出现函数级键、file:line 漂移过大);④V0 对拍差异非零(行为零变化被证伪);⑤PARITY 触面处置分歧;⑥断言面被下游兜底吸收致判据绑不上(按 test-conventions §8.4 出口呈报);⑦S13 键恶化或基线外新键。
## 15. 测试削弱申报(允许改动的旧断言及理由)
零申报——本批不删任何断言、不改判据阈值、不缩扫描面、不把真实入口换成下层直调;测试改指只动成员寻址(断言条件与期望值零变化);新增断言四条(V1/V2/V4/V5,全部内嵌既有函数)。未申报的削弱由独立验收审计判红。
## 16. 独立验收审计
合并前由未参与实现的会话或子代理执行;报告落 `reports/iter<N>-验收审计-<日期>.md`。审计至少做四件事(test-conventions §8.7):逐行核对第 11 节对照表(测试存在、真执行、尾缀可 grep、真实入口未绕过改动点);抽查判据绑定面(V2 两快照同键、V4 攻击单基值、V5 引用同一性——当轮真实跑批执行过);检查测试削弱(对照第 15 节零申报);核对全部「非行为改动」判定依据(零漂移证明是否在当轮真实跑批中成立、PARITY 批准凭据在案)。未过不得合并。
## 17. 代拍板白名单(允许 agent 自行拍板的微决策)
1. 迁移函数与改指处头注/行注的指址微调(词表与语义不动——「指址须真」纪律)。
2. 调用面改指的机械改写(排版、注释同步、行内换行)。
3. 断言失败消息尾缀编号分配与措辞(〔编排归约 Vn〕系列)。
4. 新件私有成员与小函数命名微调(职责语义不变、公有面契约名逐字不动)。
5. 宿主 _init 内两新件建件语句的次序微调(约束不变:_facts 无依赖先建、_rounds 在两件建齐与 bind 接线之后)。
超清单决策记入实现报告「实现决定记录」节。
## 18. 待裁点
零待裁点——五项待裁点(设计文档 §13)已由用户 2026-10-29 全裁闭合(第 2 节裁决记录),完美账写口升级已按推荐案采纳落卡。**零待裁点,开工门=U0**。编队前置:迭代 42(gdstyle 尾波清偿批,含轴丙 BoardInstaller)合回之后开工;T0 按当轮 master 重测对账。
@@ -0,0 +1,195 @@
# 需求卡片——测速循环批(tune_sim_controller 循环内 await 真实消除)
> **版本状态**:v1.0 定稿——零待裁点(2026-10-29 用户裁:信号步进状态机形态、收尾置假还原作为已申报行为改动、双实现对拍入批、错误路径差异接受并文档化)。
> **接收方**:待办清单条目「零豁免五键清偿批——S13 余量五键真修四卡(2026-10-29 登记,来源=会话提及)」——本卡为其四卡中的测速循环批卡。
> **来源**:reports/设计-测速循环去await-2026-10-29.md(2026-10-29 设计闭合)。**唯一事实源**:`reports/设计-测速循环去await-2026-10-29.md` + `design/engineering/architecture/architecture.md` v1.25「测试与质量域」S13 测量面豁免注销句(2026-10-29 零豁免裁:原循环内 `await` 豁免〔2026-10-27〕注销——tune_sim_controller 改 process_frame 信号常驻连接+步进状态机,每帧一局、帧相位逐点对齐;随批申报行为改动一处:运行态收尾由「每局置假」还原为「整批收尾单次置假」,消除与 wd8/ui_tune_probe 断言面的静态矛盾)。
## 1. 目标与完成定义
这批做什么:把 S13 静态质量闸(gdstyle)在册裸键 `game/presentation/tune_sim_controller.gd|quality/await-in-loop` 真实消除——`run(n)` 的 for 循环内 `await process_frame` 改为 process_frame 信号常驻连接+步进状态机(每帧回调执行一局、步尽次帧收尾断连),`run()` 只留函数级一次 `await _batch_finished` 保持协程身份;改后全文件零 for/while,该键从文本形态根除、此文件对这个键结构性免疫。随批执行两项已裁事项:把「每局置假」还原为「整批收尾单次置假」(已申报行为改动——消除与两个在库断言面的静态矛盾);新增双实现对拍套件,把帧相位等价论证变成当轮真实执行证据。
什么状态算完:
1. `tune_sim_controller.gd` 全文件零循环、`await` 仅 `run()` 函数级一处;`python tools/gdstyle_gate.py` 对账该裸键消失(消失键不参与红判定)、无基线外新键。
2. 测量语义逐点等价(第 4 节四判据)经双实现对拍在当轮真实跑批中证明——五面对拍全等;wd8 三断言与 ui_tune_probe ⑤ 零改动转绿。
3. diff 中已申报行为改动恰一处(收尾置假还原,对照表 V3 行),无第二处行为改动。
4. 脚本错误中断路径差异作为声明缺口写入实现报告(禁静默)。
5. 批末代码域闸全绿;实现报告与反哺点清单写齐方算收口。
## 2. 设计事实源
设计依据唯一出处=`reports/设计-测速循环去await-2026-10-29.md`(2026-10-29 设计闭合,零待裁点):§4 推荐案(process_frame 信号步进状态机伪代码结构)、§5 等价性证明清单(四判据+已声明缺口)、§6 键账预期、§7 行为零变化风险点。架构面凭据=`design/engineering/architecture/architecture.md` v1.25「测试与质量域」S13 测量面豁免注销句(2026-10-29 零豁免裁落文)——豁免注销、行为改动申报面与本卡一致。待办清单条目「零豁免五键清偿批」状态=文档设计已闭合+待写卡(本卡即其中一卡的写卡段产出)。
## 3. 现状事实(代码级,2026-10-29 实查;开工 T0 按当轮 master 重测重锚——行号基线为本日 master)
- `game/presentation/tune_sim_controller.gd`(全件 68 行):`run(n)` 在 :36-52——:37 置运行态真、:40-42 开共享 JSONL 日志会话、:43 `panel.set_sim_running(true)`、:44 进度 0/n、:45 建 stats 六键束、:46 取自动策略驱动、:47-50 for 循环体(`_run_one_level` → 进度串 → :50 `await panel.get_tree().process_frame`——命中键的语句)、:51-52 收尾(close_session+报告注入)。`_run_one_level` 在 :56-68(5 参),**尾部两行 :67 `panel.set_sim_running(false)`/:68 `_running = false` 每局执行一次**(潜伏红本体,见下)。类成员 5(db/panel/_base_hp/_driver/_running)+常量 2(:7 SEED_BASE=4200、:8 PlaytestLogger preload);头注 4 行。
- 断言面一〔wd8〕`game/tests/unit/presentation/standee_fx_sweep_test.gd:126-134`:FakePanel(内类 Node,:20-40——setter 面并入树供 get_tree)+FakeDriver(:44-55——`run_level` 回调内读 `ctrl.is_running()` 逐局记 `seen`);:129 直构控制器(字典夹具 db)、:131 `await ctrl.run(2)`(run 必须可等待、挂起至整批完成的契约)、:132-134 三断言——`drv.seen == [true, true]`/收尾 `not ctrl.is_running() and not panel.running`/报告非空。套件在 run_all.gd manifest 在册(res://tests/unit/presentation/standee_fx_sweep_test.gd,expect 0)。
- 断言面二〔探针 ⑤〕`game/probe/ui_tune_probe.gd:63-83`::65-66 设滑条与 N=10、:67 `press_simulate_for_probe()`(真实按钮 pressed 信号链)、:68-71 守卫环(`while main.debug_overlay.is_running()` 逐帧等——SIM_GUARD_FRAMES=1800 在 :16)、:72-73 预算内未完成判红、:74-83 输出四串断言(关卡完成率/关卡完成剩余 HP 均〔口径换代 V7〕/败北节点/N=10)。面板语义面 `debug_overlay.gd`:`set_sim_running` :81-83 → `_sync_sim_button` :107-110(模拟与两层调试两钮禁用+「模拟中…」文案——浮窗运行态贯穿整批的可见面)、`is_running` :77-79。
- 调用面 `game/presentation/main_debug_flow.gd`:`_on_tune_simulate` :72-77——守卫(活跃结算/冒险早退)后 `root._tune_sim.run(n)` **不 await 调用**(返回的协程态丢弃——新形态必须保持此调用形态可用、零改动);`_start_debug_levels` :84 守卫读 `root._tune_sim.is_running()`(两层调试入口互查守卫)。
- 静态矛盾推演(设计文档 §2.3——T0 实跑定谳)::67-68 每局执行 → wd8 首局完成即把两个运行态置假 → `drv.seen` 实测 `[true, false]` 必红;探针按下返回后首局已在同一同步段内跑完、运行态已假 → 守卫环立即退出 → 输出停在进度串 → 四串断言全红。推断这两行原在循环之后(「循环体提函数」搬运时被卷入提取体——设计文档 §2.3),wd8 写于 d8 批且当时必绿可反证;两面均不在近期批次的关联档选测覆盖内(套件名与涉案文件无字面关联、probe_gate --full 非恒跑三保险),潜伏红因此未暴露。
- 键账:`tools/gdstyle_baseline.txt:15` = 该文件唯一在册键(await-in-loop 裸键,基线 16 键之一)。S13 扫描面=产品码三目录(game/core+data+presentation——probe/sim/tests 不在面,`game/tests/static_scan.sh` S13 头注在案);S8 文件集=九文件显式清单(static_scan.sh :317——不含本件);S9/S10 扫描面同不含 game/tests/。
- 产品码 process_frame 订阅面(T0 实查项):本件 :50(循环内 await)+`settlement_fx_view.gd:94`(play_damage_number 内一次性 await 等文本度量——战斗结算呈现期,与模拟批不并存)。现库无「run 途中新增订阅者」场景。
- 报告渲染面 `game/presentation/hud_presenter.gd` :197-218 `tune_sim_report`(静态函数,零触碰计划):空数组 `_mean`/`_p90` 双守卫(:221-227/:230-235)、完成率分母 `maxi(1, n)`(:206)——n=0 退化路径渲染安全(本批对拍 n=0 案的前提,实查在案)。
- 能力表现状:`game/tests/README.md` 能力表零 tune_sim/调试浮窗行;锚到本批断言宿主套件的唯一既有行=「站桩敌人呈现与结算演出落点」(代表用例 `standee_fx_sweep_test.gd:_init`——wd8 断言所在函数)。
## 4. 设计契约(违反即返工的红线条款,标 🔴 触碰=L3 停机呈报)
- 🔴 **测量语义逐点等价**(设计文档 §5 四判据逐条落卡,双实现对拍为当轮执行证据):
① 步数与帧数一一对应不变——每局恰占一帧:第 i 局恒在调用点同步段(i=0)或第 i 帧信号发射点(i≥1),收尾恒在第 n 帧发射点,n=0 退化路径两形态同为同步收尾零帧;
② 每步工作量与执行相位不变——步进体=同一 `_run_one_level`+同一进度语句;执行点同为 emit process_frame 帧首段(await 恢复点与 connect 回调在引擎内同处一列连接、同一 emit 内被同步调用——设计文档 §4.2 逐步对齐表);
③ 终止条件与终止时读数不变——终止=计数走满 n;close_session/运行态复位/报告注入在同帧执行;
④ 输出逐字不变——报告=未触碰的 `HudPresenter.tune_sim_report`;stats 是 (种子, atk_pct, hp_pct) 的纯函数、帧时点不进测量值;JSONL 由未触碰的自动策略逐行写、close 时点同帧。
违反即返工;等价性对拍失败=L3 停机呈报。
- 🔴 **行为改动唯一=收尾置假还原**(已申报——对照表 V3 行):`_run_one_level` 尾部两行(:67-68)删除,运行态复位收进 `_finish_batch()` 收尾单次执行;禁任何其他行为漂移——`_on_tune_simulate` 不加运行态早退守卫(设计文档待裁点 3 备选否决)、发布态零触碰、探针①–④⑥–⑩ 段零触碰、`HudPresenter`/`PlaytestLogger`/`sim/level_autoplay.gd`/`debug_overlay.gd` 零触碰。
- 🔴 **脚本错误中断路径差异=声明缺口**(设计文档 §5 缺口 1,接受并文档化):GDScript 无错误陷阱 API、差异不可消除——旧形态步进体内脚本错误=协程死亡静默停摆(运行态永真、报告永不落);新形态=计数未推进、次帧重试同一步(确定性错误逐帧重试,探针 1800 帧守卫可抓;生产态=持续重试的可见坏,与旧「静默卡死」同级不同形)。实现报告文档化义务(T3),禁静默、禁造第三条路(错误陷阱/守卫兜底均已否决);测量批遇错本就整批作废,两形态都不产出可用读数。
- 🔴 **S8 结算路径 await 零命中面不触碰**:本件不在 S8 文件集(九文件显式清单实查不含本件);本批零触碰 S8 文件集与一切闸件。
- 🔴 **拆分边界纪律**(判据权威=code-conventions §1.1,卡内执行条款):本批零拆出单元——步进状态机收编本件(职责语句与不拆理由见第 8 节);①拆出单元须有可陈述职责语句与单一变化原因;②命不出名字、只能说「剩下的成员」的打包=凑计数袋,禁;③「过阈值」只作发现信号——本批键消除靠形态根除、不靠拆件凑数;④按纪律拆不出内聚单元→停卡呈报;⑤禁沿阈值轴拆。
- 🔴 **RNG 与种子零触碰**:SEED_BASE=4200 与逐局种子切分(SEED_BASE+i)零变化——stats 是种子纯函数是等价性论证的前提。
- 🔴 **注释纪律**:新增头注/注释零变更叙事(「由 await 改为信号」类句禁——沿革归 git);S11 注释禁词由术语表解析供给,新增注释用白话描述现行形态与信号契约。
## 5. 范围边界
做什么:第 3 节四件事——T0 现状定谳(实跑两断言面)、`tune_sim_controller.gd` 步进状态机改造+收尾还原、双实现对拍套件、键账对账与收口。
不做什么(明示去向):
- 零豁免其余四键(main.gd 类变量 49、battle_orchestrator 类变量 38、board_cell_unit 30、standee_body 19)——各归组合根注册面批/战斗编排归约批/呈现层状态件批(同条目四卡,待办清单在册)。
- `tools/gdstyle_baseline.txt` 禁实现批中途刷新——批末由用户人工重生成(第 6 节)。
- `_on_tune_simulate` 运行态早退守卫——不收件(+1 行为面、system_test 前置断言随之需复核,代价大于收益,设计文档待裁点 3 否决)。
- `design/` 整个目录、两份根流程清单——实现批禁写;该改的点列反哺点清单。`game/tests/README.md`:测量面专属能力行已随本卡写卡段同批入表(「调参测速批量模拟」行——写卡同批义务,grilling 复核订正),实现批禁写红线不变。
- 探针其余段与套件其余断言族(standee_fx_sweep 的 wd2/wd4/wd5/wd12 面)零触碰;`architecture.md` 其余豁免条目(battle_orchestrator 第三条注销句现状化归战斗编排归约批反哺点)零触碰。
## 6. 关联文档同步面
| 文档 | 关联点(本批实现会改变它的哪条陈述) | 同步义务 |
|---|---|---|
| design/engineering/architecture/architecture.md | 「测试与质量域」S13 测量面豁免注销句(v1.25——「设计闭合、实现批建件」批后现状化;随批申报行为改动句随之成为已实施事实) | 设计权威文档——实现批禁直改;逐条列进 `reports/iter<N>-反哺点-<日期>.md`(豁免注销句现状化),用户裁决后归文档批落文 |
| game/tests/README.md | 能力表——测量面专属能力行「调参测速批量模拟(逐帧步进与统计读数)」已随本卡写卡段同批入表(真实入口=批量模拟入口,代表用例=本卡对拍套件);manifest 计数行随套件增减浮动(自助声明,零义务) | 机械面文档——实现批禁写;入表已完成于写卡段(本卡 v1.0 同批),实现期零改动 |
| tools/gdstyle_baseline.txt | tune_sim await-in-loop 裸键(:15,该文件唯一在册键)随键消失成死键 | 重生成为人工专用——批末由用户执行 `python tools/gdstyle_gate.py --refresh`(键数 16→15,降幅 <10% 不需 --force);禁实现批中途刷新 |
| design/gdd/(全目录) | 无关联文档——测量工具私有机制改造,不改游戏规则与玩家可见行为(tune_sim 全链路发布态不可达,设计文档 §7.3) | 无修订预期;契约句被触碰=停卡呈报走反哺点通道 |
## 7. 卡前文件结构图(本批新建/修改文件全列)
| 文件 | 新增/复用 | 职责 | 行为改动 |
|---|---|---|---|
| game/presentation/tune_sim_controller.gd | 复用(改造) | 批量模拟控制器——process_frame 信号常驻连接+步进状态机;收尾单点 `_finish_batch`;全文件零循环 | 行为改动一处(V3 收尾还原)+结构改形(V1——零漂移由对拍证) |
| game/tests/unit/presentation/tune_sim_batch_parity_test.gd | 新增 | 双实现对拍配对套件——遗留 await 形态夹具(内类)+五面对拍断言 | 非行为改动(测试面) |
| game/tests/run_all.gd | 复用(改造) | manifest 增一行(新套件注册,expect 0) | 非行为改动(测试基建) |
结构图与第 8 节互指:新增件一件(对拍套件),其「为什么不能复用/落点唯一」理由见第 8 节;其余两行均为既有文件改造。
## 8. 落位与可复用性预检
- **步进状态机不引入新文件(本件内改造)——为什么不拆新件**:单一职责已在件内——`tune_sim_controller` 的职责就是批量模拟控制,步进机制(每帧一局的节律与帧相位承载)是它的私有运行机制,随批生灭(run 期活成员,批末失效下次 run 重写),没有独立于批量模拟的存在意义;拆出「步进机」件命不出独立职责语句=凑计数袋(code-conventions §1.1 判据②④禁)。复用面核查:全仓 grep 无信号步进机同职责实现可复用;其余四形态(SceneTreeTimer 链/Timer 节点/递归协程/线程)已被设计文档 §3 逐一否决(相位不同或键不消)。
- **对拍套件落 `game/tests/unit/presentation/` 的唯一性与命名**:落点唯一——与断言宿主 wd8 同目录同协议(extends SceneTree+Kit 收尾),单元层承载;命名 `tune_sim_batch_parity_test.gd`(领域命名、无 ID 前缀);grep 同名与同义标识符实查无第二处。**遗留 await 形态副本全仓只许此一份**——产品码禁留第二实现(旧形态只活在测试夹具内);tests/ 不在 S13/S8/S9/S10 扫描面(扫描面=产品码三目录与 B1 九文件清单,实查在案),夹具内循环 await 合法在册。
- **复用面**:夹具的假面板/假驱动复用 wd8 的形态先例(FakePanel/FakeDriver 同形——代码在各套件内自建,不跨套件共享 helper,禁散落);收尾复用 `test_kit.gd` 的 Kit.finish(零断言专用退出码协议)。
- **分层与交互**:控制器保持 RefCounted、零 Node 入树;process_frame 连接经 `panel.get_tree()` 取树(与现状同一出口);对拍套件 `--script` 模式零 autoload 依赖(db 用字典夹具,同 wd8 :129 先例);零新增跨层出口、零数值表读取、零随机。
## 9. 实现规范预算(gdstyle 默认阈值对账:公开方法 ≤20、类变量 ≤15、单函数分支 ≤8、返回 ≤6、参数 ≤5、局部 ≤10、函数 ≤50 行)
本批零新增产品码文件(改造 `tune_sim_controller.gd` 本件)——改造后该文件键账预期(设计文档 §6 逐规则落卡):
| 规则 | 预期 | 依据 |
|---|---|---|
| quality/await-in-loop(裸键,本案标的) | **消除** | 全文件零 for/while;await 仅 `run()` 函数级一处(`await _batch_finished`)——结构性免疫 |
| quality/allocation-in-loop | 不命中 | 文件零循环;`PlaytestLogger.new()` 在 run 顶层(现状即如此) |
| max-function-length ≤50 | 达标 | run 约 22 行、`_step_frame` 约 12 行、`_run_one_level` 删两行后约 10 行 |
| max-branches ≤8 | 达标 | `_step_frame` 一个 if/else;run 一个 if/else |
| max-local-variables ≤10 | 达标 | run 局部 3(logger/stats/autoplay——余者转成员);`_step_frame` 局部 1 |
| max-returns ≤6 | 达标 | 全 void |
| max-parameters ≤5 | 临界持平 | `_run_one_level` 5 参逐字保持;两个新函数 0 参 |
| max-class-variables ≤15 | 达标 | 现 5+新增 6=11(`_batch_finished` 信号若被工具计入成员则 12——两值均达标;成员皆 run 期活承载,非凑数袋) |
存量触面一查:基线实查该文件唯一在册键=await-in-loop 裸键(`tools/gdstyle_baseline.txt:15`)——S13 键较登记值只降不升,裸键消失即清偿;死键由批末用户人工 `--refresh` 自然清去(16→15,降幅 <10% 不需 --force)。新增测试件不在 S13/S9/S10/S8 扫描面(第 3 节实查在案);仍按 test-conventions §6 全类型标注自律(参数/返回值/容器全带标注)。
## 10. 禁为机检文本保留无效成员(重构类卡必填条款)
禁止为迎合 S13 机检消息文本(含计数)保留或新增无效成员/别名;本批新增 6 个 run 期活成员皆为 `_step_frame`/`_finish_batch` 读写的承载(`_finished` 若实现期确认零读者,可删——见第 14 节白名单 3,成员 11→10 键账只降不升);机检键与卡片契约互斥时,实现段一律停卡呈报,不得自造第三条路。
## 11. 任务卡 T0..T3(估时为区间;工作量限制只属迭代层——合计 1–1.5 工作日)
**T0 现状定谳与读数重锚(0.25 工作日)**
- [ ] 实跑 wd8 单套件(开发期最窄确认,不作验收凭据):`godot --headless --path game --script res://tests/run_all.gd -- --only=standee_fx_sweep`——记录 :132-134 三断言实况;红=潜伏红定谳成立。套件若因在册无关缺陷先红于 wd8 断言(待办清单「迭代 41 测试债修复」在册的 set_trans 一类),先核该债修复状态、不得借本批顺手修非申报面——读数以「wd8 断言可达性」为准呈报(L2 记录)
- [ ] 实跑 ui_tune_probe 单探针:`…console.exe --headless --path game res://probe/ui_tune_probe.tscn`——记录 ⑤ 守卫环与输出四串实况
- [ ] 判读:两面按第 3 节静态推演红=前提成立开工;两面实跑全绿=潜伏红证伪=设计前提崩塌——L3 停卡呈报(第 13 节)
- [ ] 按当轮 master 重锚第 3 节全部 file:line 与成员计数;漂移处就地改卡并记录
- [ ] 实查产品码 process_frame 订阅面——预期两处(本件 :50+settlement_fx_view.gd:94);出现 run 途中新增订阅者场景=L2 记录+代码评审注记(设计文档 §5 缺口 2)
产出:潜伏红定谳读数(改动前基线证据,独立验收审计要核对);重锚后行号。
**T1 步进状态机改造(0.25–0.5 工作日)**
- [ ] `tune_sim_controller.gd` 头注增 `_batch_finished` 信号契约一行(code-conventions §2.1——每信号一行:发射时点=报告注入与运行态复位之后;消费方=run() 自身收尾放行,外部 `await run(n)` 经此放行;现 4 行→5 行;禁变更叙事句)
- [ ] 增 `signal _batch_finished` 与 6 个 run 期活成员(名字按设计文档 §4.1 逐字:`_sim_n: int`/`_sim_i: int`/`_sim_stats: Dictionary`/`_sim_autoplay`/`_sim_logger`/`_finished: bool`)
- [ ] `run(n)` 改形:setup 段(:37-46 语句逐字保持);n>0 分支——`is_connected` 守卫 connect `panel.get_tree().process_frame`(恰好连接一次,迭代 39 先例)→ `_step_frame()` 首步同步执行(与 await 形态「第 0 局在调用栈内跑完」对齐)→ `await _batch_finished`(函数级单次 await——键消除落点);n=0 分支直调 `_finish_batch()`(循环零进同步收尾,与 await 形态一致不挂起)
- [ ] 新增 `_step_frame() -> void`(0 参):`_sim_i < _sim_n` 分支——`_run_one_level(_sim_autoplay, _sim_stats, _sim_i, panel, _sim_logger)`+`panel.set_sim_progress("模拟中:%d/%d …" % [_sim_i + 1, _sim_n])`(串逐字保持现码 :49)+`_sim_i += 1`;else 分支——先 disconnect(防再入)→ `_finish_batch()` → `_batch_finished.emit()`
- [ ] 新增 `_finish_batch() -> void`(0 参):`_finished = true` → `close_session()` → `panel.set_sim_running(false)` → `_running = false` → `panel.set_sim_report(HudPresenter.tune_sim_report(_sim_n, panel.atk_pct(), panel.hp_pct(), _sim_stats, _base_hp))`(四语句相对次序按此草图,对两断言面不可观测——白名单 5)
- [ ] `_run_one_level` 删尾部两行(:67-68),其余逐字保持(5 参签名不变)
- [ ] 孤立验证:`--only=standee_fx_sweep` 全绿(wd8 三断言零改动转绿=潜伏红消除实证)+ui_tune_probe 单探针绿(probe_gate --full 段承载)
- [ ] 自检:新增头注/注释零变更叙事、S11 禁词零命中
取用:T0 重锚行号。产出:`_batch_finished` 信号与 `_step_frame`/`_finish_batch` 签名(T2 对拍新形态即产品码本体);wd8 转绿读数。
**T2 双实现对拍夹具(0.25–0.5 工作日)**
- [ ] 建 `game/tests/unit/presentation/tune_sim_batch_parity_test.gd`(extends SceneTree,Kit 收尾,全类型标注):内类 FakePanel(Node——wd8 同形 setter 面,另带进度串/报告记录数组)+FakeDriver(RefCounted——固定返回值两档〔victory/defeat,同 wd8 :53-55 取值〕,零随机;逐局记录帧索引与运行态读数,帧索引经宿主注入的计数 Callable 读取)+AwaitLoopRunner(RefCounted——现 `run()` await 形态逐字副本,含自身 `is_running()` 镜像;**与产品码的申报差异仅两处**:尾部两行按还原语义置收尾、批末把 stats 六键束存夹具成员供对拍读取)
- [ ] 对拍驱动:两形态各经 `run(n)` 真实入口驱动(新形态=真 TuneSimScript 直构,旧形态=夹具直构;同参假面板/假驱动各自实例);拓扑钉死——测试宿主先连 process_frame 帧计数、后启动两形态(两形态下「计数先于步进体」相对次序同构,序列可比);n=3 常规+n=0 退化两案
- [ ] 五面对拍断言(落点 `_init`,尾缀〔测速 V1〕..〔测速 V5〕):V1 帧索引序列——两形态逐局记录序列逐位相等(每步恰一帧+相位同点的执行证据);V2 运行态序列——驱动内 `is_running()` 读数序列逐位相等+收尾双运行态假相等;V3 进度串序列——面板记录的 set_sim_progress 串序列逐位相等;V4 stats 六键逐位——夹具暴露 stats 与测试内按假驱动固定返回值重算的六键期望(wins/dmg_all/hp_left_win/hp_boss/rounds_all/death_nodes)逐键相等;V5 报告全文逐字——两形态面板记录的 set_sim_report 串逐字相等,n=3 案含「关卡完成率/关卡完成剩余 HP 均/败北节点/N=」渲染面(n=0 案只断逐字相等——空 stats 渲染无剩余 HP 行,`_mean`/`_p90` 空守卫实查在案)
- [ ] `run_all.gd` manifest 增行 `{"path": "res://tests/unit/presentation/tune_sim_batch_parity_test.gd", "expect": 0}`
- [ ] 孤立验证:`--only=tune_sim_batch_parity` 绿+`--only=standee_fx_sweep` 复跑绿
取用:T1 的产品码新形态与 `_batch_finished` 放行语义。产出:五面对拍断言面(对照表 V1/V2 行验收主体)。
**T3 键账对账与收口(0.25 工作日)**
- [ ] S13 对账:`python tools/gdstyle_gate.py` 输出确认 tune_sim await-in-loop 裸键消失(消失键不参与红判定)、无基线外新键
- [ ] 关联档复跑:`--only=standee_fx_sweep,tune_sim_batch_parity`+ui_tune_probe(probe_gate --full 段)全绿
- [ ] 批末代码域闸全绿:`tools/run_all_gates.sh --code`(改动含 game/ 下非 .md 行为载体——`--code` 档)
- [ ] 错误路径声明缺口写入实现报告(第 4 节 🔴 条全文迁入——禁静默)
- [ ] 产出物落位卡:`reports/iter<N>-实现报告-<日期>.md`(各卡状态+实机目检总清单〔本批零目检项〕+遗留读数义务+实现决定记录)与 `reports/iter<N>-反哺点清单-<日期>.md`(第 6 节同步面逐条落点)写齐,方算收口
编队注记:本卡与零豁免其余三卡无产品码触面交集(本卡触面=tune_sim_controller.gd+game/tests/ 两件);run_all.gd manifest 行与并行批可能交叠——编队归编排段(待办清单条目口径:编队待迭代 42 合回)。
## 12. 验证闸——改动—验收对照表
域口径:本批改动全为 `game/` 下非 .md 行为载体——批末跑代码域闸;里程碑步(T 段)出口跑一次全套闸,波内修复只做出红最小单元的最窄确认,新增测试先行孤立验证再并入全套(测试执行两入口铁规不破)。三件保险(冒烟/系统测试/静态扫描)恒跑;02 单元与集成按关联档选套件——**本卡显式申报套件:standee_fx_sweep_test(wd8——套件名与涉案文件无字面关联,diff 推导可能漏选,特此申报)+tune_sim_batch_parity_test(新增)**。测试方式两分法:本批全部调试接口自动化(假驱动/假面板直构+真实按钮信号链探针),零用户目检项(tune_sim 全链路发布态不可达——登记不阻塞条款零登记项)。**静态判据申报(不入对照表,test-conventions §8.4 出口)**:S13 await-in-loop 裸键消除无独立运行期提交面——判据=`python tools/gdstyle_gate.py` 与 `game/tests/static_scan.sh` 退出码(T3 执行),属静态判据+评审注记申报观测面局限;对拍夹具不在 S13/S8/S9/S10 扫描面的声明同此口径(扫描面=产品码三目录与 B1 九文件清单,static_scan.sh 实查在案)。**声明缺口(不入对照表——证明做不出出口)**:脚本错误中断路径差异不可消除,见第 4 节 🔴 条,实现报告文档化(T3)。**能力清单**:本批新增能力一行「调参测速批量模拟(逐帧步进与统计读数)」已随本卡写卡段同批入表(写卡同批义务,grilling 复核订正原「既有名锚定+后续入表」悬置形态)——对照表三行能力列改锚该行;manifest 计数行随套件增减浮动。
| 行 | 需求点 | 改动(文件:行/行为) | 验收测试(名称+落点+尾缀) | 层级 | 真实入口 | 判据绑定面 | 能力行 |
|---|---|---|---|---|---|---|---|
| V1 | 步进状态机改造(循环内 await 消除的落码面) | tune_sim_controller.gd :36-52 改形(run 函数级单次 `await _batch_finished`,全文件零循环)+:56-68 拆出 `_step_frame`/`_finish_batch` | 复用 wd8 驱动形态 `await ctrl.run(2)`(:131——run 协程身份契约,零改动);新增对拍 V4/V5(stats 六键逐位+报告逐字,落点 tune_sim_batch_parity_test.gd:_init,尾缀〔测速 V4/V5〕) | 单元 | TuneSimScript 直构(字典夹具 db+假面板+假驱动,wd8 :129 同款)经 `run(n)` 真实入口;对拍两形态同入口 | run 可等待(await 挂起=整批完成放行)+stats 六键逐位+报告全文逐字 | 新增:调参测速批量模拟(逐帧步进与统计读数) |
| V2 | 双实现对拍(帧相位等价的执行化证据) | tune_sim_batch_parity_test.gd 新建+run_all.gd manifest 增行 | 新增五面对拍断言〔测速 V1–V3〕:帧索引序列/运行态序列/进度串序列逐位相等(落点 tune_sim_batch_parity_test.gd:_init) | 单元 | 两形态各经 `run(n)` 真实入口(n=3 常规+n=0 退化);帧索引经测试宿主 process_frame 计数 | 两形态五面记录序列逐位相等(每步恰一帧+相位同点的当轮执行证据——判据本体) | 新增:调参测速批量模拟(逐帧步进与统计读数) |
| V3 | 行为改动——收尾置假还原(已申报唯一行为改动) | tune_sim_controller.gd :67-68 删(每局置假)→ `_finish_batch` 收尾单次置假 | 复用 wd8 三断言〔wd8〕(`drv.seen == [true, true]`/收尾 `ctrl.is_running()` 假+`panel.running` 假/报告非空——零改动)+ui_tune_probe ⑤ 守卫环与输出四串(:63-83——零改动) | 单元+探针 | wd8 假驱动回调读 `is_running()`(`await ctrl.run(2)`);探针 `press_simulate_for_probe()` → 按钮 pressed 信号链 → `run(10)` → 守卫环逐帧复查 | 驱动逐局运行态读数序列 [true, true]+收尾双运行态假+守卫环 1800 帧预算内退出+`output_text()` 四关键串(浮窗运行态贯穿整批的可观测提交面) | 新增:调参测速批量模拟(逐帧步进与统计读数) |
反向核对:diff 中行为改动共一处(V3 行);其余为非行为改动——V1 结构改形(零漂移判据=对拍五面全等+wd8/probe 零改动转绿)、V2 测试面新增、manifest 增行(测试基建)。孤儿断言:对拍五断言挂 V1/V2 两行,无孤儿。
## 13. 异常分级
- **L1 自救**:编译错、断言尾缀措辞、夹具记录数组名笔误——就地修复,重跑最窄单元确认。
- **L2 记录继续**:T0 套件因在册无关债先红于 wd8 断言(记录可达性事实,不借批顺手修);行号重锚漂移(就地改卡记录);产品码 process_frame 订阅面发现第三处(记录+评审注记——非 run 途中新增场景不红)。
- **L3 停机写报告等用户**:①T0 潜伏红证伪——两面实跑全绿=「每局置假系搬运卷入」前提崩塌,停卡退回写卡段重裁行为改动申报面;②等价性对拍失败——五面任一不等=测量语义漂移,设计前提崩塌;③机检预算互斥——改造后实测键超第 9 节预算或基线外新键=上游缺陷停卡退回写卡段(含禁为机检保留无效成员条款冲突);④S13 对账 await 键未消或冒新键;⑤判据绑不上可观测提交面(证明做不出=停卡呈报,禁自造注入破坏或回退取证)。
## 14. 代拍板白名单(逐条列,超清单记实现报告「实现决定记录」)
1. 断言失败消息尾缀〔测速 V1–V5〕的分配与措辞。
2. 头注 `_batch_finished` 契约行措辞(信号语义与发射时点不变)。
3. `_finished` 成员零读者确认后删去(成员 11→10——键账只降不升,行为与断言面零变化)。
4. 夹具假面板/假驱动成员命名微调(记录语义不变;与 wd8 同形自建、不跨套件共享)。
5. `_finish_batch` 收尾段四语句相对次序按第 11 节 T1 草图次序落码(对两个断言面不可观测——实现期查 git 历史原序可进一步对齐)。
6. 排版机械改写(空行、preload 顺序、注释换行)。
## 15. 待裁点
零待裁点,开工门=U0。(裁决记录:2026-10-29 用户裁四点——①信号步进状态机形态采纳〔SceneTreeTimer 链/Timer 节点/递归协程/线程四形态淘汰依据见设计文档 §3〕;②收尾置假还原作为已申报行为改动随批实施;③双实现对拍入批;④脚本错误中断路径差异接受并文档化。)
## 16. 测试削弱申报
无申报项——wd8 三断言与 ui_tune_probe ⑤ 零改动零削弱;对拍五断言为新增非改判;夹具与产品码的两处申报差异(收尾还原语义+stats 暴露成员)系新增件自身设计、设计文档 §5 在案,非既有断言削弱。禁删断言、禁放宽阈值、禁缩小扫描面、禁把真实入口换成下层直调;未申报的削弱由独立验收审计判红。
## 17. 独立验收审计
合并前由未参与实现的会话或子代理执行;报告落 `reports/iter<N>-验收审计-<日期>.md`,未过不得合并。审计至少做五件事:①逐行核对第 12 节对照表(测试存在、真的执行、尾缀可 grep、真实入口未绕过改动点);②抽查判据绑定面——帧索引序列是否真从 process_frame 发射点记录、对拍拓扑两形态是否同构可比、V3 行判据是否钉在运行态提交面而非终态兜底;③核对 T0 定谳证据在案(改动前 wd8/probe 红读数——潜伏红链条完整,缺 T0 读数=审计不过);④核对行为改动唯一性——diff 中除 V3 外无第二处行为改动;⑤检查测试削弱(对照第 16 节零申报)与内部字段直查受控例外(本批零直查——新形态 stats 经报告公开面观测)。
## 18. MC/数值与 RNG 零触碰声明
本批零数值改动、零数据表改动、零 RNG 流变化:SEED_BASE=4200 与逐局种子切分零变化(stats 种子纯函数前提);对拍夹具零随机(假驱动固定返回值)。MC 对拍不跑、零跑批义务(无数值改动——`sim-data/README.md` 档位硬闸:无数值改动零跑)。
@@ -0,0 +1,337 @@
# 需求卡片——组合根注册面批(main.gd 类变量归 15:界面注册面+三域句柄容器)
状态行:v1.0 定稿——零待裁点(2026-10-29 用户裁:注册面拓扑一门面+三域容器、合同机器迁入、别名消灭清单整体确认;实现层细目授权 agent 按设计文档执行)
接收方:待办清单条目「零豁免五键清偿批——S13 余量五键真修四卡(2026-10-29 登记,来源=会话提及)」——本卡为其四卡之首(组合根注册面批)。
来源:reports/设计-组合根注册面-2026-10-29.md(2026-10-29 设计闭合,**唯一事实源**);architecture 权威=design/engineering/architecture/architecture.md v1.25(2026-10-29——「模块归属·呈现层」表 ui_registry 行、「呈现层装配与会话生命周期」节屏成员寻址迁注册面句=原 S13 豁免登记注销、RunScope 节)。
## 1. 目标与完成定义
这批做什么:把 main.gd(组合根)里散着的屏壳、覆盖层一级句柄与视觉层合同表收进一个「界面注册面」——一个不挂树的 RefCounted 门面件(ui_registry.gd)加三个按领域分的句柄容器(ui_screens/ui_battle/ui_modals),探针和系统测试对界面元素的引用从 `main.X` 一级地址改成 `main.ui.<域容器>.<句柄>` 三段式地址。同时消灭 7 个探针兼容别名/转发成员、退役 6 个 main 纯转发模态方法。main.gd 类变量从 49 降到 15,S13 基线键真实还债,architecture 在册的 S13 豁免登记随批注销。
**行为零变化**:装配序、信号接线、层序(树序=登记序=z 序)、RunScope 会话生命周期、RNG 消费序全部零变化;探针断言只换地址、不换判据。
完成定义(全部满足才算完):
1. 五闸主证全绿——probe_gate 默认段+`--click`+`--full`、render_gate golden 零差异、run_smoke、run_system_test、run_all 02 单元与集成(main.gd 触组合根=横切面,按 AGENTS.md 关联档口径回落全部套件)。
2. static_scan 过——四新文件零新基线键(S9 全类型标注、S10 头注);main.gd 类变量实测 15(键账对账批末申报,基线 refresh 由用户发令)。
3. 改址完整性自检——按 49 名逐名 grep,`game/` 下旧一级路径 `main.<旧名>`/`root.<旧名>`/`self.<旧名>` 残留=0,报告留档。
4. 产出物落 `reports/`——实现报告、反哺点清单、验收审计报告(独立审计未过不合并)。
**编队注记与估时**:本卡与「战斗编排归约批」(battle_orchestrator 拆 RoundCycle/BattleFacts 两件——architecture v1.25 轴丁设计闭合、待写卡)和「测速循环批」(tune_sim_controller 步进状态机——architecture v1.25 S13 测量面豁免注销设计闭合、待写卡)同代待编排;三批无同文件交叠(本批触面=main.gd+main_ui_build+三流程件+探针/测试面)。与迭代 42(在飞:gdstyle 尾波清偿批+level_runner 商店委托层拆除)**存在文件交叠**——并排卡「level_runner 商店委托层拆除」触面含 main.gd(1 处)、main_adventure_flow(6 处)、main_overlay_flow(2 处),全在本批触面集内(grilling 复核证伪原「无交叠」声明,订正);**本批开工前置=迭代 42 合回 master**,T0 按合回点重测改址计数。另与「呈现层状态件批」共享 ui_input_probe.gd 触面(本批改 main.X 地址面、该批改四处 u.face.* 读面)——同代编排时禁并行、先后皆可。估时区间 **3–4 个工作日**(设计文档 §8),低于迭代冻结线(5 个工作日),可编批;编入哪个迭代由迭代编排段定。
## 2. 现状事实
全部行号为 **2026-10-29 实查——本批编入在 gdstyle 尾波补件批相关迭代之前/之后均须 T0 按 T0 时点 master 重测重锚**。
1. `game/presentation/main.gd`(915 行)共 **49 个类变量**(逐名清点 main.gd:61–148,含 3 个委托属性);S13 基线键 `game/presentation/main.gd|quality/max-class-variables = 49`(阈值 15)在 tools/gdstyle_baseline.txt 在册,architecture v1.25 在册 S13 豁免登记〔2026-10-27「组合根类变量面即探针契约面」〕已随 v1.25 注销、待本批真实还债。
2. 视觉层合同机器四样全在 main.gd:`LAYER_CONTRACT` 常量(main.gd:39–59,19 项含 host/shell/tags 标注)、`_apply_layer_contract()`(main.gd:254–279,全仓唯一 move_child 落位点)、`_layer_node(key)`(main.gd:227–248,19 键 match)、`_register_modal(m, tags)`(main.gd:218–224,anchors preset+flow.register)。
3. 探针兼容别名/接缝成员 7 个:`board_view`(main.gd:95)、`ap_bar`(main.gd:96)——赋值点 main_ui_build.gd:48–49;`_modals`(main.gd:129,赋值 main_ui_build.gd:245);`_row_queue`(main.gd:111–113,委托属性读 `_row_pacer.pending_rows()`);`_seed_edit`(main.gd:74,赋值 main_ui_build.gd:208);`_settlement_stop_pending`(main.gd:134–143,读=is_armed()/写=arm()/disarm());`_deferred_modal`(main.gd:148–150,读 `_modal_flow._deferred`)。
4. main 纯转发模态方法 6 个:`_open_modal_after_playback`(main.gd:156–158)、`_on_pump_ended`(main.gd:161–163)、`_open_modal`(main.gd:282–284)、`_close_modal`(main.gd:285–287)、`_on_modal_closed`(main.gd:288–290)、`_input_locked`(main.gd:292–295)——各自一行转呼 `_modal_flow` 真方法。另有一个纯转发方法同批退役:`_flush_row_queue`(main.gd:516,一行转呼 `_row_pacer.flush`)——`_row_pacer` 句柄迁 ui.screens 后调用方 `pacing_queue_test.gd:103` 改调 `main.ui.screens.row_pacer.flush()`(表 D 归宿行)。
5. 装配承接件 main_ui_build.gd:`build(root)` 八步(main_ui_build.gd:21–29),赋值目标全走 `root.X` 一级成员(main_ui_build.gd:38–51 等);`pump_ended` 注入点 main_ui_build.gd:62;context 束注入 `open_modal/close_modal`(main_ui_build.gd:144、168);`_apply_layer_contract()` 末位调用 main_ui_build.gd:247。
6. 消费面引用量(设计文档 §0 机械统计,T0 实跑重计):探针+系统测试 `main.X` 成员引用约 **867 处**;四个流程承接件(main_adventure_flow/main_overlay_flow/main_debug_flow/main_ui_build)`root.X` 引用约 200–350 处(设计文档 §0 与 §3.2 两处统计口径不一,以 T0 映射表脚本实跑计数为准)。抽查实证:ui_input_probe.gd:34–43(seed_edit/level_screen)、system_test.gd:94–109(LAYER_CONTRACT、_layer_node、V2 句柄等价五连比)、smoke_boot.gd:68–75(`main.get()` 6 处)、pacing_queue_test.gd:108/132/147/149(`_row_queue` 3 处+`board_view` 1 处)、source_guard_test.gd:69–77(V1d 层序单口断言,现扫 main.gd 单文件)、theme_projection_test.gd:724–725(V6 断言 main.gd 含 `debug_overlay.diagnose_requested.connect(_on_diagnose_pressed)` 串)。
7. 留 main 的 14 成员(对账见表 B)全部是组合根自身状态、组合根拆件引用、autoload 读视图;`run_scope` 引用(探针约 173 处)零迁移。
8. 探针段构成(architecture「测试与质量域」probe_gate 行):默认段 ui_input_probe/ui_struct_probe/layout_probe/ui_contrast_probe/screen_flow_probe,`--click` 加 ui_click_probe,`--full` 加 ui_probe/ui_tune_probe/t17_defer_probe/fx_probe。
9. meta_progression_forge_test 经 `load("res://presentation/main.gd")` 直呼 static `build_adventure_params`——留 main,零迁移(main.gd:366–376)。
10. 本批不涉 RNG/数值/存档触面;PARITY 触面(battle_orchestrator.gd)不在 diff,无 MC 义务。
## 3. 设计契约(违反即返工,标 🔴 触碰=L3 停机呈报)
- 🔴 **行为零变化**:装配序与 add_child 顺序、信号连接语句逐条不变;层序合同表条目、顺序、tags、host/shell 标注**逐字零变化**只换宿主文件;`_begin_session`/闲时会话/整节点 queue_free 机制一字不动;RNG 消费序零触碰;呈现层订阅禁令与核心写调用唯一出口纪律零触碰。
- 🔴 **探针断言语义零变化**:改址只换地址不换判据——断言条件、尾缀(既有〔装配生命批 V1〕〔装配生命批 V3〕等保留)、消息语义不动;禁借改址删断言、放宽阈值、缩小扫描面。
- 🔴 **拆分边界纪律五条**(判据权威=code-conventions §1.1,此处写红线不复制定义):①每个拆出单元须有可陈述的职责语句与单一变化原因(四件各一句,见 §12 表,实现报告逐件一行承载);②拆出单元须有集体身份——命不出名字、只能说「剩下的成员」的打包=凑计数袋,禁;③「过阈值(49→15)」只许作发现信号,作拆分或收拢动机即违规;④按纪律拆不出内聚单元→停卡呈报走豁免通道,禁硬拆凑绿;⑤禁保留/新增无效成员与别名凑数——本批方向是净消灭(7 成员+6 方法),实现期发现任何「为保地址兼容」新增的转发壳即违契约。
- 🔴 **禁为机检文本保留无效成员**:禁止为迎合机检消息文本(含计数)而保留或新增无效成员/别名;机检键与本卡契约互斥时(如实测出新基线键 NEW 红)一律停卡呈报,不得自造第三条路(详见 §13 条款节)。
- 🔴 **测试削弱申报制**:允许改动的旧断言全集见 §8「测试削弱申报」,未申报的删改由独立验收审计判红。
## 4. 范围边界
做:ui_registry+三域容器建件;合同机器四样迁驻;main.gd 49→15 改形;main_ui_build 与三流程件改址;探针九件+probe_ui_util+smoke_boot+system_test+pacing_queue_test 改址;V1d/V6 源码断言重锚;七别名与六转发方法消灭。
不做(明示去向):
1. architecture.md 直改——实现批禁写 `design/`,ui_registry 行现状化与 main_ui_build 行层序句改指走反哺点通道(§6)。
2. game/tests/README.md 改动——实现批禁写;写卡段义务已核=零增删零改行(§6)。
3. modal_stack.gd/modal_flow.gd 语义改动——两件零触碰,本批只改它们的消费方地址。
4. RunScope/会话生命周期机制、row_pacer 排播时序、T17 挂起编排——零触碰。
5. S13 豁免登记第二/三条(tune_sim_controller、battle_orchestrator)——原文不动,归「战斗编排归约批」「测速循环批」。
6. board_cell_unit/standee_body/board_view 悬停域等结构债——归迭代 42 尾波清偿批,不收件。
7. 基线 refresh——`python tools/gdstyle_gate.py --refresh` 由用户发令人工跑(净减 1 键,低于 10% 骤降守卫,无需 --force);实现批只做键账对账申报。
8. MC/数值验证——无数值改动零跑。
## 5. 关联文档同步面
| 文档 | 关联点(本批实现会改变它的哪条陈述) | 同步义务 |
|---|---|---|
| design/engineering/architecture/architecture.md(设计权威——实现批禁直改) | ①「模块归属·呈现层」ui_registry 行现登记「实现批建件」态,实现后应现状化;②同表 main_ui_build 行「层序逻辑不在此件——唯一事实源仍是 `main.LAYER_CONTRACT` + `_apply_layer_contract()`」句在实现后失效(唯一事实源迁 ui_registry.LAYER_CONTRACT+ui.apply_layer_contract());③「呈现层装配与会话生命周期」节屏成员寻址迁注册面句 v1.25 已落、实现后核对措辞与实况一致 | 反哺点通道:把上列 ①②③ 逐条列进 `reports/iter<N>-反哺点-<日期>.md`(改哪一节、改成什么、依据=设计文档 §3.3 建议句),用户在会话中裁决后归文档批落文 |
| game/tests/README.md(机械面——实现批禁写) | 本批零新增能力(改址只换地址,能力集不变);受影响存量行核对:「模态覆盖层编排与输入锁」行真实入口(ModalFlow 两个公开方法)与代表用例(modal_flow_test.gd:_init 等)不变;「结算明细带逐行呈现与排播节奏」行代表用例 pacing_queue_test.gd:_init 不变(`文件:函数` 锚不受成员改址影响) | 写卡段义务已当场核完=**零增行、零删行、零改行**;批末收尾只核对表上名字与实际落地一致(改名则回表) |
| design/gdd/ 无关联文档 | 行为零变化,任何系统文档陈述不受影响;层序唯一事实源属 architecture 不属 GDD | 无(本行占位——按规约查不出也要写明) |
## 6. 卡前文件结构图(本批新建/修改文件全列)
| 文件 | 职责 | 新增/复用 | 行为改动? |
|---|---|---|---|
| game/presentation/ui_registry.gd | 界面注册面门面:三容器属性+LAYER_CONTRACT+node(key) 合同寻址+apply_layer_contract(root) 唯一落位口 | 新增(预检 §12) | 非行为改动(新建件承载既有合同——落点变化,对照表行 1/2) |
| game/presentation/ui_screens.gd | 屏壳与全屏容器域句柄册(9 成员) | 新增(预检 §12) | 非行为改动(对照表行 3) |
| game/presentation/ui_battle.gd | 战区视图域句柄册(5 成员) | 新增(预检 §12) | 非行为改动(对照表行 3/4) |
| game/presentation/ui_modals.gd | 模态层域句柄册+ModalFlow 持有+register_layer(14 成员) | 新增(预检 §12) | 非行为改动(对照表行 3/7) |
| game/presentation/main.gd | 组合根改形:49→15;合同机器与转发方法迁出;内部取址改 ui.*;头注追加注册面句 | 修改 | 非行为改动(纯结构——装配/接线/层序/RNG 零变化,四闸主证;对照表行 2/6/7) |
| game/presentation/main_ui_build.gd | 八步赋值目标改 root.ui.*;context 束与 pump_ended 注入改址;_seed_edit/_modals 赋值行退役 | 修改 | 非行为改动(八步顺序/add_child 序/连接语句逐条不变;对照表行 3) |
| game/presentation/main_adventure_flow.gd/main_overlay_flow.gd/main_debug_flow.gd | root.X 同表映射(模态口改指 root.ui.modals.flow;句柄读改 root.ui.*) | 修改 | 非行为改动(对照表行 3/7) |
| game/probe/ 九探针+probe_ui_util.gd(凡 T0 映射表命中的 main.X 引用件) | 旧地址→main.ui.* 机械改写 | 修改 | 非行为改动(断言语义零变化;对照表行 4/6) |
| game/tests/smoke_boot.gd | get() 键改址(4 改 2 留) | 修改 | 非行为改动(对照表行 3) |
| game/tests/system_test.gd | main.X 改址(V1a/V1c/V2 句柄等价/V3 矩阵取址两处) | 修改 | 非行为改动(判据零变化;对照表行 1/5) |
| game/tests/unit/contracts/source_guard_test.gd | V1d 重锚(单文件扫描→全目录扫描,判据强化) | 修改 | 非行为改动(断言改写已申报;对照表行 8) |
| game/tests/unit/presentation/theme_projection_test.gd | V6 断言串改新连接串 | 修改 | 非行为改动(断言改写已申报;对照表行 9) |
| game/tests/unit/presentation/pacing_queue_test.gd | board_view/_row_queue 改址(3+1 处) | 修改 | 非行为改动(对照表行 6) |
不触碰:modal_flow.gd/modal_stack.gd/row_pacer.gd/ui_assembler.gd/run_scope.gd/meta_progression_forge_test.gd(static 入口零迁移)/全部 core 与 data。
## 7. 任务卡 T0..T4
### 7.1 地址契约(全批唯一映射依据——表 A/B/C/D 与设计文档 §1.2 对账表同源)
**表 A:迁入注册面的 28 个 main 成员**(容器内成员名去下划线=公共地址面):
| 现成员(2026-10-29 行号) | 新地址 | 现成员 | 新地址 |
|---|---|---|---|
| `_menu_screen`(:100) | ui.screens.menu_screen | `legend_overlay`(:116) | ui.modals.legend_overlay |
| `_camp_screen`(:101) | ui.screens.camp_screen | `node_overlay`(:117) | ui.modals.node_overlay |
| `_adventure_screen`(:102) | ui.screens.adventure_screen | `level_screen`(:83) | ui.modals.level_screen |
| `_start_overlay`(:79) | ui.screens.start_overlay | `curio_overlay`(:78) | ui.modals.curio_overlay |
| `_battle_root`(:84) | ui.screens.battle_root | `_end_overlay`(:80) | ui.modals.end_overlay |
| `_inter_overlay`(:81) | ui.screens.inter_overlay | `shop_overlay`(:118) | ui.modals.shop_overlay |
| `_inter_label`(:82) | ui.screens.inter_label | `camp_overlay`(:119) | ui.modals.camp_overlay |
| `debug_badge`(:126) | ui.screens.debug_badge | `settings_overlay`(:121) | ui.modals.settings_overlay |
| `_row_pacer`(:105) | ui.screens.row_pacer | `status_panel`(:122) | ui.modals.status_panel |
| `stage`(:91) | ui.battle.stage | `career_overlay`(:123) | ui.modals.career_overlay |
| `log_view`(:92) | ui.battle.log_view | `save_select_overlay`(:124) | ui.modals.save_select_overlay |
| `info_panel`(:93) | ui.battle.info_panel | `confirm_dialog`(:75) | ui.modals.confirm_dialog |
| `board_zone`(:94) | ui.battle.board_zone | `debug_overlay`(:125) | ui.modals.debug_overlay |
| `settlement_fx`(:97) | ui.battle.settlement_fx | `_modal_flow`(:128) | ui.modals.flow |
**表 B:留 main 的 14+1**:db、run_scope、save_manager、meta、settings_store、logger、_debug_entry、_confirm_consumer、_confirm_consumer_slot、_debug、_treasure_ui、_bonus、_camp_pres、_tune_sim(保留理由逐个=组合根自身状态/拆件引用/autoload 读视图,见设计文档 §1.2 第二表)+新增 `ui: UiRegistry`。改后 15,恰在阈内。
**表 C:消灭的 7 个别名/接缝成员**:
| 成员 | 本体 | 消灭后地址 |
|---|---|---|
| board_view(:95) | =board_zone.board_view | ui.battle.board_zone.board_view |
| ap_bar(:96) | =board_zone.ap_bar | ui.battle.board_zone.ap_bar |
| _modals(:129) | =_modal_flow.stack | ui.modals.flow.stack |
| _row_queue(:111) | 委托属性=_row_pacer.pending_rows() | ui.screens.row_pacer.pending_rows()(同一 Array 引用,语义不变) |
| _seed_edit(:74) | =debug_overlay.seed_edit | ui.modals.debug_overlay.seed_edit.text(main._seed_value 唯一消费点) |
| _settlement_stop_pending(:134) | 委托属性读=is_armed()写=arm()/disarm() | run_scope.settlement_stop_timer 直呼同名面 |
| _deferred_modal(:148) | 委托属性=_modal_flow._deferred | ui.modals.flow._deferred |
**表 D:方法/函数级改址**:
| 旧地址 | 新地址 | 消费方 |
|---|---|---|
| main._layer_node(key) | main.ui.node(key) | system_test V1c(实查 source 点 system_test.gd:97;设计文档记 3 处——T0 重计) |
| main._register_modal(m, tags) | ui_modals.register_layer(m, tags)(逐字迁入:anchors preset+flow.register) | 仅 _apply_layer_contract 内部消费,随迁 |
| main._apply_layer_contract() | main.ui.apply_layer_contract(root)(root 作参传入,main_ui_build.gd:247 调用点改) | 装配尾唯一调用点 |
| main._open_modal(m) | main.ui.modals.flow.open(m) | 探针各 1 处+流程件 root. 共约 23 处(T0 重计);main 内部调用点(_on_confirm_accepted 等)同改 |
| main._close_modal(m)/main._on_modal_closed(m) | main.ui.modals.flow.close(m)(信号 bind 目标 main_ui_build.gd:99/209 改 flow.close.bind) | 同上 |
| main._input_locked() | main.ui.modals.flow.locks_input() | 探针 18 处(T0 重计)+main._on_board_action/_on_stop_pressed/_on_refresh_confirmed 内部 |
| main._open_modal_after_playback(m) | main.ui.modals.flow.open_after_playback(m) | 流程件 root. 2 处+探针(T0 重计) |
| main._on_pump_ended | main.ui.modals.flow.pump_ended | row_pacer.pump_ended 注入点 main_ui_build.gd:62 |
| smoke_boot `main.get("_start_overlay"/"debug_badge"/"legend_overlay"/"status_panel")` | `main.get("ui").<域>.<名′>`(get 只解析一层,后续走公共字段) | smoke_boot.gd:70/73/74/75;`get("run_scope")`/`get("settings_store")` 零迁移 |
| source_guard V1d 串 | 重锚:扫全 `game/presentation/*.gd`,`move_child(` 只允许出现在 ui_registry.gd 的 apply_layer_contract 函数体内(从扫单文件变扫全目录——判据强化) | source_guard_test.gd:69–77 |
| main._flush_row_queue() | main.ui.screens.row_pacer.flush()(转发壳随 `_row_pacer` 迁移退役) | pacing_queue_test.gd:103 |
| theme_projection V6 串 | 改断言新串 `ui.modals.debug_overlay.diagnose_requested.connect(_on_diagnose_pressed)`(连接语句本体随 T2 改写 main.gd:209) | theme_projection_test.gd:724–725 |
### 7.2 新件接口块(T1 定义,T2 起逐字取用;类型标注义务=S9 过)
```
# game/presentation/ui_registry.gd —— 界面注册面(RefCounted,不挂树,零信号连接,零会话期引用)
class_name UiRegistry
extends RefCounted
const ModalStack := preload("res://presentation/modal_stack.gd")
const LAYER_CONTRACT: Array[Dictionary] = [ …main.gd:39-59 内容逐字迁入,一项不增不减不改… ]
var screens: UiScreens
var battle: UiBattle
var modals: UiModals
func node(key: String) -> Node # 合同寻址:_layer_node 的 19 键 match 逐字迁入
func apply_layer_contract(root: Control) -> void # 落位算法逐字搬运(move_child 单口;登记经 modals.register_layer)
# game/presentation/ui_screens.gd —— 屏壳与全屏容器域(RefCounted,纯字段无方法)
class_name UiScreens
extends RefCounted
var menu_screen: Control
var camp_screen: Control
var adventure_screen: Control
var start_overlay: Control
var battle_root: Control
var inter_overlay: Control
var inter_label: Label
var debug_badge: Button
var row_pacer: RowPacer # 经 preload 常量取型(res://presentation/row_pacer.gd 非 class_name 全局)
# game/presentation/ui_battle.gd —— 战区视图域(RefCounted,纯字段无方法)
class_name UiBattle
extends RefCounted
var stage: BattleStageView
var log_view: BattleLogView
var info_panel: HeroInfoPanelView
var board_zone: BoardZoneView
var settlement_fx: SettlementFxView
# game/presentation/ui_modals.gd —— 模态层域(RefCounted)
class_name UiModals
extends RefCounted
var flow: ModalFlow
var legend_overlay: LegendOverlay
var node_overlay: NodeOverlay
var level_screen: LevelMapScreen
var curio_overlay: CurioPickOverlay
var end_overlay: BattleEndOverlay
var shop_overlay: ShopOverlay
var camp_overlay: CampOverlay
var settings_overlay: SettingsOverlay
var status_panel: StatusPanel
var career_overlay: CareerOverlay
var save_select_overlay: SaveSelectOverlay
var confirm_dialog: ConfirmDialog
var debug_overlay: DebugOverlay
func register_layer(m: Control, tags: Array = []) -> void # _register_modal 逐字迁入
```
(main.gd 现有类型标注逐字沿用:ui_battle/ui_modals 十八句柄的类型名=main.gd:78–125 在用全局类名;ui_screens 三屏壳标 Control,若 T1 实测场景根基类不符,按代拍板白名单第 6 条取实际基类。)
### 7.3 T0——读数重锚与对账(估时 0.5 个工作日)
- [ ] 按 T0 时点 master 重测重锚本卡全部行号与计数:main.gd 类变量实数(gdstyle 读数)、合同机器四样行位、七别名与六转发方法行位、六转发方法的全部调用点清单(main 内部+流程件+探针+system_test 分文件计数)。
- [ ] 49 成员逐一对账:对照本卡表 A/B/C 逐名核对仍在位、仍归该档(迁移 28/留 14/消灭 7)——任何一名对不上=L3 停卡呈报(设计文档 §1.2 对账表为第二依据)。
- [ ] 映射表脚本生成+对账:探针九件+probe_ui_util+smoke_boot+system_test+四流程件的 `main.X`/`root.X` 全量计数与旧→新映射(机械生成+人工复核语义位——属性读写约 750 处、方法调用四类、字符串键 6 处、源码断言 2 条);设计文档 867/350/200 三处统计口径以本次实跑为准并在实现报告记数。
- [ ] 未登记源码断言排查:grep `presentation/main.gd` 于 game/tests+game/probe 全部源码断言面——只许 V1d/V6 两条命中;新发现=L3 停卡补申报,禁自行改判。
- [ ] 迁移函数对账:查 tools/gdstyle_baseline.txt 中 main.gd 的 `_apply_layer_contract`/`_layer_node`/`_register_modal` 源函数键——branches/returns/函数长有超默认登记值的,迁移即拆函数(拆分不改语义)。
- [ ] 孤立验证(改前基线读数):`python tools/gdstyle_gate.py`(采集 main.gd=49 读数)+`godot --headless --path game --script res://tests/run_all.gd -- --only=source_guard`(绿)。
- 取用:本卡 §7.1 四表。产出:重锚后的映射表与对账表(实现报告附件节,T2/T3/T4 消费)。
### 7.4 T1——注册面与三域容器建件(估时 1 个工作日)
- [ ] 按 §7.2 接口块建 ui_registry.gd:LAYER_CONTRACT 自 main.gd:39–59 逐字迁入(ModalStack 常量引用随迁);`node(key)` 19 键 match 逐字;`apply_layer_contract(root)` 落位算法逐字搬运(move_child 单口语义不变)。
- [ ] 建 ui_screens/ui_battle/ui_modals(成员与类型按 §7.2;ui_modals.register_layer 自 main.gd:218–224 逐字迁入);四件全类型标注、`_init` 不收参(容器由门面构造)。
- [ ] 四件 class_name(UiRegistry/UiScreens/UiBattle/UiModals)+跑一次编辑器扫描刷新全局类缓存+同步 .uid(code-conventions 语言纪律 5——T2 main.gd 类型标注 UiRegistry 在 --script 模式可解析的前置);文件头 `##` 注释介绍模块(禁变更叙事、禁文档反向链接)。
- [ ] 孤立验证:`game/tests/static_scan.sh`(S9 四新件零红+S10 头注过+S13 四新件零新键)+`godot --headless --path game --script res://tests/run_all.gd -- --only=source_guard`(V8 全库扫描仍绿——新件零字符串 Callable)。
- 取用:T0 映射表。产出:四件公开面(UiRegistry.new()/.screens/.battle/.modals/.node(key)/.apply_layer_contract(root)/modals.register_layer(m, tags)——T2 逐字消费)。
### 7.5 T2——main.gd 改形与装配/流程件改址(估时 1–1.5 个工作日)
- [ ] main.gd 新增 `var ui: UiRegistry`;`_ready` 在 `_build_ui()` 之前 `ui = UiRegistry.new()`(容器随门面构造;装配在 _ready 建闲时会话之前完成——时序零变化)。
- [ ] 表 A 28 成员迁出:main 内部全部取址同步改 `ui.*`(含 main.gd:199–200 启动态两行、_seed_value:911、_on_confirm_accepted/_start_adventure/_resume_from_menu/_replay_locked_click 等内部调用点改指 ui.modals.flow.*/ui.screens.row_pacer.pending_rows());合同机器四样自 main 删除(随 T1 迁驻)。
- [ ] main_ui_build.gd:八步赋值目标改 `root.ui.<域>.<名′>`(八步顺序、add_child 顺序、连接语句逐条不变);`root._seed_edit` 赋值行(:208)删除;`pump_ended` 注入改 `root.ui.modals.flow.pump_ended`(:62);`root._modals` 赋值行(:245)保留至 T4;context 束 overlay/toast/start_overlay/board_view 键值改址(:137–147、:163–169,注入时点与值不变);`_apply_layer_contract` 调用改 `root.ui.apply_layer_contract(root)`(:247)。
- [ ] 三流程件 root.X 按表 A/D 同表映射(root._open_modal/_close_modal/_open_modal_after_playback/_input_locked → root.ui.modals.flow.*;`_settlement_stop_pending` 写点改 `run_scope.settlement_stop_timer.arm()/disarm()`——写点计数 T0 对账)。
- [ ] smoke_boot.gd get() 改址(4 改 2 留,§7.1 表 D)。
- [ ] source_guard_test.gd V1d 重锚为全目录扫描(尾缀〔注册面 V1〕);theme_projection_test.gd V6 改断言新串(尾缀〔注册面 V2〕)——两条改写即 §8 申报的测试改动全集。
- [ ] 孤立验证:`python tools/run_smoke.py`(冒烟绿=装配链完整)+`godot --headless --path game --script res://tests/run_all.gd -- --only=source_guard,theme_projection,meta_progression_forge`(三套件绿——V1d/V6 重锚后绿、static 入口零变化)+`python tools/gdstyle_gate.py`(main.gd 类变量读数记录——此轮含 7 别名=22,基线键 49 内不红,读数进实现报告)。系统测试与探针此轮预期红(消费面未改址——T3 收口),不构成本卡验证面。
- 取用:T1 四件公开面。产出:main.ui.* 地址面全量生效的组合根(T3 消费)。
### 7.6 T3——探针/系统测试/单元批量改址(估时 1 个工作日)
- [ ] 探针九件+probe_ui_util 按 T0 映射表机械改写:属性读/写改 `main.ui.<域>.<名′>`;四类方法调用按表 D;`var bv = main.board_view` 型局部承接改 `var bv = main.ui.battle.board_zone.board_view`(每文件 1–2 处)。
- [ ] 接缝三件:ui_struct_probe 的 `main._modals` → `main.ui.modals.flow.stack`(登记序断言);t17_defer_probe 的 `main._deferred_modal` → `main.ui.modals.flow._deferred`(挂起态断言);ui_click_probe 的 `_settlement_stop_pending` 读点 → `main.run_scope.settlement_stop_timer.is_armed()`。
- [ ] system_test.gd 改址:V1c 的 `main.LAYER_CONTRACT`→`main.ui.LAYER_CONTRACT`、`main._layer_node`→`main.ui.node`;V2 句柄等价断言(:107–109)改 ui 地址(等价语义不变:ui.battle.board_zone.board_view == ui.screens.adventure_screen.board_view 型);V1a 候选清单与全件 main.X 逐表映射;V3 矩阵 `_face_snapshot` 的 `main._modal_flow`→`main.ui.modals.flow`、`main._row_pacer`→`main.ui.screens.row_pacer`(其余四持件取址不变)。
- [ ] pacing_queue_test.gd:`main.board_view`→`main.ui.battle.board_zone.board_view`(:132);`main._row_queue`→`main.ui.screens.row_pacer.pending_rows()`(:108/:147/:149,实查 3 处)。
- [ ] 改址完整性自检:映射表驱动 49 名逐名 grep——`game/` 下(探针/tests/流程件/main 自身)旧一级路径 `main.<旧名>`/`root.<旧名>`/`self.<旧名>` 残留=0,报告留档(实现报告对照表挂行)。
- [ ] 孤立验证:`tools/probe_gate.sh --click --full`(全段退出码 0)+`python tools/run_system_test.py`(V1–V9 摘要 0 失败)+`python tools/run_smoke.py`+`godot --headless --path game --script res://tests/run_all.gd -- --only=pacing_queue,source_guard`。
- 取用:T2 地址面。产出:全部消费面新地址(T4 前提——别名/转发方法零消费方)。
### 7.7 T4——别名与转发方法消灭+批末收口(估时 0.5–1 个工作日)
- [ ] 删 main.gd 七别名/接缝成员(表 C——此点已零消费方)与六转发方法(§2 第 4 条清单);删 main_ui_build.gd:245 `root._modals` 赋值行;main.gd 类变量终态 **15**。
- [ ] 文件头注随迁改写:main.gd 头注追加一句「界面句柄与层清单在 ui 注册面(ui_registry.gd)」;main_ui_build.gd 头注「层序唯一事实源」句改指 ui_registry(指址改写、词面语义不变)。
- [ ] 逐卡扫尾孤立验证:`tools/render_gate.sh`(golden 零差异)+`tools/probe_gate.sh --click --full`+`python tools/run_smoke.py`+`python tools/run_system_test.py`+`godot --headless --path game --script res://tests/run_all.gd -- --only=pacing_queue,modal_flow,source_guard,theme_projection,meta_progression_forge`。
- [ ] 批末全量:`tools/run_all_gates.sh --code` 全绿(main.gd 触组合根=横切面——02 单元与集成按 AGENTS.md 横切面口径回落全部套件;冒烟/系统测试/静态扫描三件保险恒跑)。里程碑步出口跑一次全套闸;波内修复只做出红最小单元的最窄确认;新增测试先行孤立验证再并入全套。
- [ ] S13 键账对账申报:main.gd 键 49→15 只降不升、四新件零新键;基线 refresh 由用户发令人工跑(--refresh,净减 1 键低于骤降守卫)。
- [ ] **产出物落位卡**(轻闸全绿后、合并前写齐,方算收口):`reports/iter<N>-实现报告-<日期>.md`——各卡状态+实机目检总清单(登记不阻塞:注册面改址后实机过一遍三屏切换与模态开合)+遗留读数义务(基线 refresh)+实现决定记录+改址计数与 grep 自检留档;`reports/iter<N>-反哺点-<日期>.md`——§5 同步面所列 architecture 三条逐条有落点;`reports/iter<N>-验收审计-<日期>.md`——独立验收审计(未参与实现的会话或子代理执行,未过不得合并)。
- 取用:T3 零消费方清单。产出:终态 main.gd(15 var)+三份 reports/ 产出物。
## 8. 验证闸(改动—验收对照表)
本批全部改动为**非行为改动**(结构与地址重构):每行判断依据=改前改后在同一输入上行为一致,由探针/系统测试/冒烟/渲染 golden 四闸主证(真实入口全绿),静态 grep 只作完整性辅证。调试接口/目检两分法:本批无新玩法能力,验证全走自动化载体;用户目检仅一条登记项(T4 实机过三屏与模态开合),登记不阻塞。**静态判据申报(不入对照表,test-conventions §8.4 出口——grilling 复核订正)**:S13 键账对账(main.gd 实测 15、四新件零新键、基线 refresh 由用户发令)与映射表驱动 grep 残留=0 自检无独立运行期提交面——判据=`python tools/gdstyle_gate.py`/`game/tests/static_scan.sh` 退出码与 T3 grep 自检留档,属静态判据+评审注记申报观测面局限;对照表行 2/11 只承载其运行面回归与全量闸半边。
| # | 需求点 | 改动(文件:行/行为) | 验收测试(名称+落点+尾缀) | 层级 | 真实入口 | 判据绑定面 | 能力行 |
|---|---|---|---|---|---|---|---|
| 1 | 注册面建件+合同机器迁驻(层序零变化) | 新建 ui_registry.gd(LAYER_CONTRACT main.gd:39–59 逐字迁入);ui_screens/ui_battle/ui_modals 建件 | 系统测试 V1c「合同树序链逐对保序」(system_test.gd:94–106 改址 main.ui.LAYER_CONTRACT/main.ui.node,尾缀〔装配生命批 V1〕保留) | 系统测试 | `python tools/run_system_test.py` | 运行期树序逐对保序=LAYER_CONTRACT 序(get_index 链——层序零变化的运行期提交面) | 既有:模态覆盖层编排与输入锁 |
| 2 | main.gd 改形回归(49→15 结构改形) | main.gd:61–148 改形(28 迁出+7 消灭+1 新增);六转发方法退役 | 批末 run_smoke+run_system_test 双宿主摘要 0 失败(改形回归主证;S13 键账静态判据见域口径申报) | 冒烟+系统测试 | `python tools/run_smoke.py`;`python tools/run_system_test.py` | 双宿主摘要 0 失败(改形后全链路回归面) | 既有:模态覆盖层编排与输入锁 |
| 3 | 装配与流程件改址(root.ui.*) | main_ui_build.gd 八步赋值目标;三流程件+context 束+pump_ended 注入点;smoke_boot.gd:70/73/74/75 | 冒烟主屏存活面六断言(smoke_boot.gd:64–75 改址后全绿)+系统测试 V2「组合根句柄指向屏壳成员」等价断言(system_test.gd:107–109 改址,五连比同指) | 冒烟+系统测试 | `python tools/run_smoke.py`;`python tools/run_system_test.py` | 启动态装配句柄在座且等价断言两侧同指一对象(多一跳取到同一引用) | 既有:模态覆盖层编排与输入锁 |
| 4 | 探针面批量改址(约 867 处) | 探针九件+probe_ui_util 旧地址→main.ui.*(只换地址不换判据) | probe_gate 全段退出码 0(ui_input_probe 全 case/ui_struct_probe/layout_probe/ui_contrast_probe/screen_flow_probe+--click ui_click_probe+--full ui_probe/ui_tune_probe/t17_defer_probe/fx_probe) | 探针 | `tools/probe_gate.sh --click --full`(单件形态:`godot --headless --path game res://probe/ui_input_probe.tscn` 等) | 探针经新地址取到同一节点并驱动真实输入路径(改址完整性的第一消费方主证) | 既有:棋盘悬停反馈(三语义光标/目标格边框/路径预览点迹) |
| 5 | 系统测试面改址+RunScope 生命周期零变化 | system_test.gd main.X 改址;V3 矩阵取址两处(_modal_flow→main.ui.modals.flow、_row_pacer→main.ui.screens.row_pacer) | 系统测试 V1–V9 全绿(含 V3a–V3i 九阶段×五引用面矩阵,尾缀〔装配生命批 V3〕保留) | 系统测试 | `python tools/run_system_test.py` | 第五引用面逐面同源比对(回调悬挂=红——存活性矩阵判据零变化) | 既有:模态覆盖层编排与输入锁 |
| 6 | 别名/接缝成员消灭(7 个) | main.gd:74/95/96/111/129/134/148 消灭;消费方改址(pacing_queue_test.gd:108/132/147/149、ui_struct_probe、t17_defer_probe、ui_click_probe、main 自身 4 处 _row_queue) | run_all 选跑 pacing_queue 绿(排空零分叉/零丢行/延迟双态/会话清队断言改址后判据不变)+ui_struct_probe 登记序断言+t17_defer_probe 挂起态断言 | 单元+探针 | `godot --headless --path game --script res://tests/run_all.gd -- --only=pacing_queue`;`tools/probe_gate.sh --full` | 属性链与别名取到同一对象引用(断言逐条等价——同一 Array/同一节点的可观测面) | 既有:结算明细带逐行呈现与排播节奏 |
| 7 | 六个 main 纯转发模态方法退役 | main.gd:156/161/282/285/288/292 退役;调用方改指 ui.modals.flow 五个真方法+注入点 main_ui_build.gd:62 | modal_flow 单元套件绿+系统测试 V3g 模态开合段+ui_click_probe 模态开合路径 | 单元+系统测试+探针 | `godot --headless --path game --script res://tests/run_all.gd -- --only=modal_flow`;`python tools/run_system_test.py`;`tools/probe_gate.sh --click` | 经真方法开合编排(遮挡互斥/锁谓词/挂起兜底行为面零变化——开合后可见性与锁态提交面) | 既有:模态覆盖层编排与输入锁 |
| 8 | V1d 源码断言重锚 | source_guard_test.gd:69–77 重锚为全目录扫描(move_child 只许在 ui_registry.gd apply_layer_contract 体内) | 「V1d 层序落位单口」重锚断言,尾缀〔注册面 V1〕 | 单元 | `godot --headless --path game --script res://tests/run_all.gd -- --only=source_guard` | 源码契约扫描面(扫描面>0 前置——全 presentation 目录零第二落位点) | 既有:模态覆盖层编排与输入锁 |
| 9 | V6 源码断言改串 | theme_projection_test.gd:724–725 改断言新连接串 | 「V6 转储入口连接随迁」新串断言,尾缀〔注册面 V2〕 | 单元 | `godot --headless --path game --script res://tests/run_all.gd -- --only=theme_projection` | main.gd 源码含新连接串(同一连接的宿主面改写) | 既有:UI 全局主题与按钮五态(含对比度锚) |
| 10 | 视觉零变化主证 | 全批呈现层地址重构(像素面零改动) | render_gate golden 零差异(shot_probe 七屏+菜单 golden+棋盘 golden) | 探针/golden | `tools/render_gate.sh` | 截图与基线图逐像素容差零差异(视觉零变化的独立主证——出现任何此前不存在的差异即 L3) | 既有:站桩敌人呈现与结算演出落点 |
| 11 | 改址完整性收口 | 全批改址面(49 名逐名) | 批末代码域闸全绿(`tools/run_all_gates.sh --code`,02 横切面回落全量套件);映射表驱动 grep 自检=T3 步骤义务(静态判据,见域口径申报) | 全量闸 | `tools/run_all_gates.sh --code` | 所选域全绿回执 | 既有:模态覆盖层编排与输入锁 |
**测试削弱申报**(实现期允许的旧断言改动全集,超出即审计判红):
1. V1d:扫描面从「main.gd 单文件」扩为「全 game/presentation/*.gd」——判据强化,非削弱。
2. V6:断言串从 main.gd 旧连接串改为新连接串——同一连接的宿主面改写,断言不删除。
3. 冒烟/系统测试/探针/pacing 各断言:只改地址字面,判据与既有尾缀不动——零删除、零放宽、零换下层直调。
4. 七别名+六转发方法随批退役=test-conventions §5.5 同生死条款的执行:消费方断言已全部改指新地址,旧地址无断言残留(T3 grep 自检为证)。
**独立验收审计**:入口与报告=`reports/iter<N>-验收审计-<日期>.md`;审计方=未参与实现的会话或子代理,逐行核对对照表、抽查判据绑定面、检查测试削弱、核对静态判据行的观测面局限注记;未过不得合并。
## 9. 异常分级
- **L1 自救**:单点漏改址→grep 定位补改后重跑该闸段;`--only` 选跑零命中(用法错 exit 2)→修正选词重跑;探针段超时→孤立复跑该段定位。
- **L2 记录继续**:同一红闸连续 3 次同因→升级记录并在实现报告「实现决定记录」节记因后继续最窄确认。
- **L3 停机写报告等用户**:
1. **行为零变化契约触探**——任一闸出现改前不存在的红且定位为层序/时序/接线行为变化;render golden 出现任何此前不存在的差异。
2. **机检预算互斥=上游缺陷停卡退回写卡段**——四新件或 main 终态实测超 §14 预算、或 static_scan 出基线外 NEW 红键;禁开豁免、禁自造第三条路。
3. T0 对账失败——49 名逐一对账与表 A/B/C 任一名对不上,或发现未登记的 main.gd 源码字符串断言。
4. 拆分边界④触发——按纪律拆不出内聚单元(本设计已拆出,若实现期发现表 A 归档错误的成员强行迁入会破集体身份时适用)。
## 10. 代拍板白名单(逐条列,超清单记实现报告「实现决定记录」)
1. 改址机械改写:映射表内旧→新地址的行内改写、被改行注释内旧地址字面同步更新(判据不动)。
2. 重锚断言的消息文字措辞(V1d/V6 两条——尾缀〔注册面 V1〕〔注册面 V2〕与判据不变)。
3. 迁移函数/成员头注按新宿主改写指址(词面随迁、语义不改)。
4. 探针内局部承接变量名保留或内联(`var bv` 型——判据不变)。
5. grep 自检留档在实现报告内的节名与格式。
6. ui_screens 三屏壳句柄静态类型在 Control 与实测场景根实际基类之间取(判据=S9 过+赋值编译过;成员名与地址面不变)。
7. main 内部调用点在 T2 先改真方法、转发方法留至 T4 删除的批内中间态时序(终态零转发壳)。
## 11. 待裁点
**零待裁点,开工门=U0。** 设计文档 §8 五项待裁点已于 2026-10-29 用户全裁:①注册面拓扑=一门面+三域容器;②合同机器随批迁入注册面;③七别名消灭+六转发方法退役+容器内成员去下划线——清单整体确认;④run_all 关联档口径=main.gd 触组合根按横切面回落全部套件;⑤编批归迭代编排段定(本卡估时 3–4 个工作日在冻结线内)。
## 12. 落位与可复用性预检
**复用面**(逐个排除既有件——为什么不能复用):
- **modal_flow.gd(ModalFlow)**:模态编排纯逻辑——开合编排、输入锁谓词、T17 挂起。它管行为不管地址;注册面管「元素清单、层序、寻址」,是它的宿主容器(flow 挂在 ui_modals 里)。职责语句不同,不能拿它当注册面。
- **modal_stack.gd(ModalStack)**:登记册数据结构(遮挡记账),被 ModalFlow 持有;层序合同表与三域寻址不归它。非候选。
- **ui_assembler.gd**:无态静态装配工厂——装配期造控件用完即弃,不持任何句柄;注册面是随 main 常驻的句柄容器。把「造」和「持」并进一件会让静态工厂变有态,破坏现行职责。
- **run_scope.gd**:局态节点——装的是会话状态不是界面元素清单;173 处探针引用零迁移义务已核。非候选。
- 形态先例(非复用对象):ConfigDB 迭代 41 三张域容器(config_domain_combat/run/crossrun.gd)解决过同构的成员数超标问题——本批三容器即同一形态在呈现层的落法。
**唯一面**:层序合同唯一事实源随迁 ui_registry.LAYER_CONTRACT(main.gd 侧删除,不双写);合同寻址唯一口=ui_registry.node();模态登记唯一口=ui_modals.register_layer()。2026-10-29 实查 game/presentation/ 下无 ui_registry/ui_screens/ui_battle/ui_modals 同名或同义件(architecture v1.25 登记「实现批建件」即此四名,盘上未建)——新增无第二落点。
**分层与交互面**(调用路径显式):
- 读地址路径:views/探针/流程件 → `main.ui.<域容器>.<句柄>` → 容器字段 → 节点。三段式每段有领域含义(组合根→注册面→域→元素),与 ConfigDB 的 `db.<域容器>.<成员>` 两段式同构。
- 注册面禁反向持有:不持 main、不持 run_scope、零信号连接、零核心写调用、零 `_process`——依赖单向(views→信号→组合根→core)零触碰;组合根单点装配不变(信号连接仍在组合根与 main_ui_build)。
- 构造路径:main._ready 建 `ui = UiRegistry.new()`(门面自建三容器),main_ui_build 八步向容器登记;四件全 RefCounted 不挂树(节点本体树位与 add_child 归属零变化——row_pacer 仍 add_child 到 main,注册面只持引用)。
- Core 零 UI 红线零触碰:本批改动全部在 game/presentation/ 与测试面。
## 13. 禁为机检文本保留无效成员(重构类卡必填条款)
禁止为迎合机检消息文本(含计数)而保留或新增无效成员/别名:main.gd 终态 15 个类变量必须个个有 §7.1 表 B 的职责理由,禁留空占位或替身成员凑计数;四新件的字段必须个个是表 A 在册句柄或 flow,禁加「以防万一」的空槽。机检键与本卡契约互斥时(如实测出新基线键 NEW 红、或键账与申报不符),实现段一律停卡呈报走 L3,不得自造第三条路。判据权威=code-conventions §1.1⑤。
## 14. 实现规范预算(gdstyle 默认阈值:公开方法 ≤20、类变量 ≤15、单函数分支 ≤8、返回 ≤6)
| 新件 | 公开方法 | 类变量 | 阈值判定 |
|---|---|---|---|
| ui_registry.gd | 2(node/apply_layer_contract) | 3(三容器属性;LAYER_CONTRACT 为常量不占 var) | 双达 |
| ui_screens.gd | 0 | 9 | 双达 |
| ui_battle.gd | 0 | 5 | 双达 |
| ui_modals.gd | 1(register_layer) | 14(13 句柄+flow) | 双达(余量 1——第 14 个模态句柄出现即触发拆分审视,作发现信号用) |
- 迁移函数对账:`_apply_layer_contract`/`_layer_node`/`_register_modal` 自 main.gd 迁入,T0 查 gdstyle_baseline.txt 源函数键——超默认登记值的迁移即拆函数(拆分不改语义);node(key) 的 19 键 match 与合同落位循环预期在默认分支阈内(设计文档 §7 同判断),实测出新键=基线外 NEW 红=L3 停卡(禁开豁免)。
- 存量触面一查:本批触碰的 presentation 存量件(main.gd/main_ui_build.gd/三流程件)预期「S13 键较登记值只降不升」——main.gd 49→15;main_ui_build 与三流程件零成员变化(仅语句内地址改写);达成手段=表 A/C 全量迁移+别名净消灭。
- 指标例外申报:无(本批不需要任何超默认面;main.gd 改后 15 在阈内,S13 豁免登记注销后不留新例外)。
## 15. 源码级断言与探针契约面的随批义务(防漏项清单)
1. V1d(source_guard_test.gd:69–77)与 V6(theme_projection_test.gd:724–725)随批重锚——本卡已全量排查 main.gd 源码断言面仅此两条(T0 复核义务不豁免)。
2. 探针段覆盖义务:probe_gate 必须 `--click`+`--full` 全跑——ui_click_probe 是最大改址户,只跑默认段会漏最深的改址面。
3. 冒烟 V1 族 get() 键、系统测试 V1c/V2/V3 取址、pacing `_row_queue` 三处——都在 §7.1 表 D 与 T3 清单内,T0 映射表生成后逐条打钩对账。