diff --git a/reports/需求卡片-架构审查P2代码面批-2026-11-03.md b/reports/需求卡片-架构审查P2代码面批-2026-11-03.md new file mode 100644 index 00000000..e0f61333 --- /dev/null +++ b/reports/需求卡片-架构审查P2代码面批-2026-11-03.md @@ -0,0 +1,165 @@ +# 需求卡片:架构审查 P2 代码面批(2026-11-03) + +来源:待办清单「架构审查优化讨论——全库架构审计读数的逐条裁决与整改分批(2026-10-29 登记,来源=审计发现)」条目 P2 部分(**唯一事实源**:reports/审计-全库架构审查-2026-10-29.md §5.2 EC8 项+§5.3 NODE_TYPES 项+2026-11-03 设计讨论会话用户授权〔实现层事项按代码规则与架构文档决策——EC8 退役依用户总判据 3「死代码不保留」2026-11-02 先例〕;GDD 侧规格退役凭据=arch51-docs worktree 提交 63fc3e74〔数据配置.md v1.3/战斗结算.md v1.7/棋盘生成.md v1.3〕)。 +状态:已写卡(v1.0,2026-11-03 成文)。改动面:游戏代码(含随逻辑写/改的测试代码)。 + +## 1. 目标与完成定义 + +**这批做什么**:两处零行为变更的代码面退役与单点化——审计 §5.2/§5.3 的 P2 代码遗留: + +| # | 对象 | 现状 | 终态 | +|---|---|---|---| +| R1 | EC8 热重载死链 | `config_db.gd` 门标志+两方法+两诊断(:45/:174-186);`battle_orchestrator.gd` 两处开门点(:272/:633);`reload()` 全仓零调用方、走 `load()` 命中引擎资源缓存拿不到磁盘新值——门后入口死(GDD 侧规格已随文档批退役) | 八处整段删除;配置库公开面 8→6;诊断状态机零触碰(删除面全部在 reload 体内) | +| R2 | NODE_TYPES 词表双份 | `node_map_generator.gd:10` 与 `level_table.gd:11` 各持一份(内容同、序不同);生成器 :166 校验自产节点、schema :78 校验表行——校验双活、词表双写 | 词表单点归 schema(`LevelTable.NODE_TYPES`),生成器删本地副本改 class_name 直引;两处校验语义零变化(`.has()` 只判成员、序无关) | + +**什么状态算完**:八处删除与词表改指落码、各有第 8 节对照表配对的验收断言在当轮真实跑批中通过;零行为变更证明=既有套件零转红(config_db_resolver/node_map_determinism/battle_settlement/冒烟)+结构性 sweep 恒零(第 8 节 V2/V3);代码域闸全绿;两份 reports/ 产出物(实现报告+反哺点清单)写齐。 + +**排序义务**:本卡实现排队在 reports/需求卡片-架构审查5.1封装修复批-2026-11-03.md 之后——battle_orchestrator.gd 同文件(5.1 卡重写 `_init` 与三调用点,本卡删 :272/:633 两行;后卡行号以 grep 符号锚定位)。 + +## 2. 设计事实源 + +- **审计读数**:`reports/审计-全库架构审查-2026-10-29.md` §5.2 第三行(EC8:`ConfigDb.reload()` 全仓零调用方、缓存命中拿不到磁盘新值、门被真实开合但门后入口死)+§5.3(NODE_TYPES 词表双份)。 +- **裁决凭据**:2026-11-03 设计讨论会话用户授权(实现层事项按代码规则与架构文档决策)+用户总判据 3「死代码不保留」(2026-11-02 裁,3.1+3.2 批死效果通道同款判法先例)。 +- **GDD 侧已闭合**:arch51-docs 提交 63fc3e74——数据配置.md v1.3(热重载规格八处摘除、软着陆例外消失=fail-fast 全域统一)、战斗结算.md v1.7(开张序列去关门步)、棋盘生成.md v1.3(热重载从句删)。本卡只收代码面。 +- **架构登记**:`design/engineering/architecture/architecture.md` v1.32——:88 ConfigDB 行(公开面 8 现态登记)、:386-387 战斗序列现态、:123 battle_orchestrator 行 `set_reload_gate` 指称。 + +## 3. 现状事实(2026-11-03 master 工作区实查,基点 ab5d75a2;开工自行复核) + +- **EC8 代码链八处**:config_db.gd:45(`var _reload_gate := false`——类变量第 9 个声明位);:174-186(注释行+`set_reload_gate` :176-177+`reload()` :180-186——内含 `push_diag("warning","reload_gated",...)` 与 `push_diag("debug","config_reloaded",...)` 两诊断与 `load_tables("res://data/tables", false)` 调用);battle_orchestrator.gd:272(begin_battle 序内 `db.set_reload_gate(true)`)与 :633(battle_over 清理序内 `db.set_reload_gate(false)`)。全仓 `reload_gated`/`config_reloaded`/`EC8` 字符串在 config_db.gd 之外零命中(grep 实核——测试/呈现/模拟/探针四层全零);`reload()` 调用方全仓零命中;tests 对 reload/热重载零引用。`load_tables` 本体(:131-159 一带)被启动加载与 resolver 装配真实消费——**只删门与 reload,load_tables 零触碰**。 +- **NODE_TYPES 双份**:`core/node_map_generator.gd:10`(`["battle", "boss", "reward", "rest", "shop"]`)与 `data/schemas/level_table.gd:11`(`["battle", "reward", "rest", "boss", "shop"]`+注释「关卡节点地图 v2.1」);消费点=node_map_generator.gd:166(`NODE_TYPES.has(String(n["type"]))`——生成器自产节点枚举校验)与 level_table.gd:78(表行加载校验)。全库第三处引用零命中(grep 实核——tests/sim/probe 全零)。两处消费均为 `.has()` 成员判定,词表序不参与行为(内容集相同)。 +- **闸面现状**:S3(core 禁表加载)对 schema class_name 直引是豁免面(warning 级人工复核口径,static_scan.sh S3 注释「schema class_name 直引豁免」)——生成器改引 `LevelTable.NODE_TYPES` 落在既有豁免形态内(同款先例=config_db 持 BoardGenTable 等四域容器);零闸件改动。 +- **S13 预算**:config_db 公开方法 8(删 set_reload_gate/reload → 6)、类变量 10(删 `_reload_gate` → 9);node_map_generator 公开面与类变量零变化(删常量不涉成员账);battle_orchestrator 15 贴顶件零变化(删两行语句不涉成员)。gdstyle 基线(tools/gdstyle_baseline.txt)对本批触件零登记键(config_db/node_map_generator/battle_orchestrator 均无登记值)。 + +## 4. 设计契约(违反即返工红线) + +- 🔴 **零行为变更**:R1 删除面全部为死代码(门标志唯一消费者 reload 自身零调用方);R2 词表 `.has()` 判定集相同——两需求的零变更证明=既有套件零转红+同种子确定链零漂移(node_map_determinism 全绿)。RNG 封闭流、明细行协议、诊断状态机、存档与断点链零触碰。 +- 🔴 **R1 删除边界**:只删 `_reload_gate` 成员+`set_reload_gate`+`reload()`+编排器两行开门点;`load_tables`/`push_diag`/诊断状态机/其余公开面零触碰;禁留兼容别名、禁留转发壳、禁注释化残段(第 13 节全款适用)。 +- 🔴 **R2 单点方向**:词表唯一落点=`data/schemas/level_table.gd`(表行校验 owner);生成器删本地 `const NODE_TYPES`,:166 改 `LevelTable.NODE_TYPES.has(String(n["type"]))`——core→data/schemas 前向边,schema class_name 直引(S3 豁免面在案形态);禁反向(schema 引 core);禁把词表搬进第三处(词表唯一落点不可迁)。 +- 🔴 **fail-fast 不破**:删除不引入任何软回退;配置加载校验路径零改动。 +- 🔴 **测试纪律**:禁变异类测试、禁撤销类取证;禁删断言/放宽阈值(第 8 节申报清单之外零删改)。 + +## 5. 范围边界 + +**收件**=R1 八处删除+R2 词表单点化+两件新 sweep 测试+既有套件回归确认。 + +**不收件**(去向已指认): +- architecture.md :88 公开面 8→6/类变量 10→9、:123 行 `set_reload_gate` 指称、:386-387 战斗序列两行——**反哺点清单承载**(实现批禁写 design/,第 6 节)。 +- GDD 侧热重载规格——已随文档批退役(63fc3e74),本卡零 GDD 触碰。 +- 闸面缺口(S1/S2/S9/S13 扫描面扩 sim/probe/tests、S8 目录域)与 S13 三处豁免存废——审计 P1 项,**不在本卡**(待办清单条目未闭合余项,后续讨论段)。 +- `ConfigDb.reload` 的诊断字符串(reload_gated/config_reloaded)随方法体整删——诊断状态机其余类别零触碰。 + +## 6. 关联文档同步面 + +实现批禁写 `design/` 整个目录与根规则文件;下表每条的落文义务全部进 `reports/iter-反哺点-<日期>.md`(N=编排段定),由用户裁决后归文档批落文: + +| 文档 | 关联点(本批实现会改变它的哪条陈述) | 同步义务(反哺点清单逐条承载) | +|---|---|---| +| design/engineering/architecture/architecture.md | :88 ConfigDB 行「公开面 8(…set_reload_gate/reload)」→ 6、类变量 10→9;:123 battle_orchestrator 行消费依赖「D2 SettlementTable + set_reload_gate」→ 去 set_reload_gate 指称;:386-387 战斗序列「set_reload_gate(true)→」「→ set_reload_gate(false)」两段删除;node_map_generator 相关行如有词表双份表述随 R2 订正(写卡期 grep「NODE_TYPES|词表」复核——现登记 :119 行「各持一份 NODE_TYPES 词表」随单点化删句) | 反哺点清单逐条列行号与改后登记内容——**机械面文档禁直改** | +| design/gdd/systems/表现与支撑/数据配置.md | 无陈述变化(v1.3 已退役全部热重载规格——零反哺确认行) | 反哺点清单写「零反哺」确认行 | +| 术语表 | 无新术语 | 确认行「零新增术语」 | + +(机检口径:本表同步义务格无一条写「随批」。) + +## 7. 任务卡 T1..T2 + +### 卡前·文件结构图 + +全部行为面=非行为改动(零行为变更批),行标【非行为】+对照表 R 行号;测试件为随逻辑写/改的测试代码。 + +``` +core 层 + game/core/config_db.gd 【非行为 R1】:45 成员删+:174-186 门与 reload 整段删(公开面 8→6、类变量 10→9) + game/core/battle_orchestrator.gd 【非行为 R1】:272/:633 两行删 + game/core/node_map_generator.gd 【非行为 R2】:10 本地词表删+:166 改 LevelTable.NODE_TYPES.has(...) +测试件(随逻辑写/改) + tests/unit/core/encapsulation_p2_sweep_test.gd 【非行为 R1–R2·新增】两处结构性零命中扫描(非空前置+正锚) + tests/run_all.gd 【非行为】manifest +1 行(sweep) +文档件 + game/tests/README.md 写卡段判断=零编辑(第 8 节能力行判断依据)——实现批禁写,批末只核对能力名引用一致 +``` + +--- + +**T1 EC8 死链退役**(估时 0.25 工作日;区间 0.25–0.5) +取用:无(本卡起点)。产出:R1 八处清零+sweep R1 组绿。 + +- [ ] 核对实现排序在案:5.1 卡(含 battle_orchestrator 触面)未合回则本批不开工;:272/:633 现址复核(行号漂移以 `db.set_reload_gate` 符号锚定位,漂移即记录进实现报告,禁改判据) +- [ ] config_db.gd::45 `_reload_gate` 成员删;:174-186 整段删(注释行+两方法+两诊断);删除后 grep 自查 `reload` 于本文件仅剩注释性零命中(load_tables 文档注释如有 reload 字样一并订正) +- [ ] battle_orchestrator.gd::272 行删(begin_battle 序内——`_damage.set_hero_ac_override(...)` 行之后);:633 行删(battle_over 清理序内——`action_economy.notify_combat_end()` 行之后);两删除点上下语句序零变化 +- [ ] 新增 tests/unit/core/encapsulation_p2_sweep_test.gd(extends SceneTree+Kit.check 主通道,全类型标注;源 token 扫描手法沿 encapsulation_sweep_test.gd〔5.1 卡新增件〕先例)R1 组:①config_db.gd 非空+含 `class_name ConfigDb` 正锚+`set_reload_gate|_reload_gate|func reload|reload_gated|config_reloaded` 全文零命中〔架构P2 V1〕;②battle_orchestrator.gd 非空+`set_reload_gate` 零命中〔架构P2 V2〕——两组均带扫描面非空前置 +- [ ] 孤立验证:新 sweep 单件先跑绿(含改前红态确认——sweep 对未删码当轮命中即红,属断言对现状的正当判红,非变异测试);随后 config_db_resolver_test 全套+battle_settlement 套件+冒烟零转红 +- [ ] run_all.gd manifest 追加 1 行:encapsulation_p2_sweep_test(expect 0,注记「R1–R2 结构性零命中扫描〔架构P2〕」) + +**T2 NODE_TYPES 单点化+批收口**(估时 0.25 工作日;区间 0.25–0.5) +取用:T1 sweep 骨架。产出:R2 清零+批收口两件。 + +- [ ] node_map_generator.gd::10 本地 `const NODE_TYPES` 删;:166 改 `if not LevelTable.NODE_TYPES.has(String(n["type"])):`——头注如有词表自述随改 +- [ ] sweep 测试 R2 组:③node_map_generator.gd 非空+`^const NODE_TYPES` 零命中+`LevelTable.NODE_TYPES.has(` 正锚〔架构P2 V3〕;④全仓 .gd 生产面(core/data/presentation)`NODE_TYPES :=` 定义恰好 1 处且落 data/schemas/level_table.gd〔架构P2 V4〕 +- [ ] 孤立验证:node_map_determinism_test 全套绿(生成链同种子逐位——R2 零行为变更主证)+关卡表加载路径(level_table 校验活检查)经既有套件覆盖零转红 +- [ ] **实现报告** `reports/iter-实现报告-<日期>.md`:各卡状态+S13 键改前改后对账(config_db 公开 8→6/类变量 10→9 现场读数)+实现决定记录 +- [ ] **反哺点清单** `reports/iter-反哺点-<日期>.md`:第 6 节同步面逐条落点(architecture.md 四处、GDD/术语确认行) +- [ ] 批末核对:README 能力名引用一致(本卡零编辑);独立验收审计(第 8 节末)未过不合并;.uid 收口=`--editor --quit` 一次后确认新测试件 .uid 随批提交 + +### 估时汇总 + +T1 0.25|T2 0.25。区间合计 0.5–1.0 工作日;**精确汇总 0.5 工作日**(超 1 工作日=超卡面估时域,须用户确认后方可续批)。 + +## 8. 验证闸(改动—验收对照表) + +测试方式两分法:下表全部走**调试接口验证**;**正常流程体验验证**=零项(零行为变更批)。判据绑被测改动特有的可观测提交面(源码零命中带非空前置与正锚/确定链同种子逐位)。 + +| 需求点 | 改动(文件:行为) | 验收测试(名称+落点+尾缀) | 层级 | 真实入口 | 判据绑定面 | 能力行 | +|---|---|---|---|---|---|---| +| R1 EC8 死链退役 | config_db :45/:174-186 删+battle_orchestrator :272/:633 删 | encapsulation_p2_sweep_test R1 组〔架构P2 V1/V2〕;config_db_resolver_test 既有全套(加载/校验/解析面零转红);battle_settlement 套件+冒烟零转红(战斗序列少两行后全链逐位) | 单元+集成 | `ConfigDB.load_tables()`(启动加载)→`BattleOrchestrator.begin_battle()`→battle_over 全链 | 源码五符号零命中(非空前置);解析/加载/结算行为面零漂移 | 既有:加载期违规表拒绝:跨表悬空/计数器前缀/真视窄域/效果类型出域;既有:轮内流与结算五段全序 | +| R2 NODE_TYPES 单点化 | node_map_generator :10 删+:166 改指 | encapsulation_p2_sweep_test R2 组〔架构P2 V3/V4〕;node_map_determinism_test 既有全套(同种子同参数必产同图逐位) | 单元+集成 | `LevelRunner` 关卡推进→节点图生成真实入口;`LevelTable` 表行加载校验 | 词表定义唯一落点(正锚计数=1);生成链同种子逐位同 | 既有:节点图生成合法性与同种子复现;既有:起关/选路/断点重生成同图(集成) | + +**零行为改动面的证据义务**:本卡两行均为非行为改动——每行零变更证明=既有套件零转红+sweep 恒零+(R2)确定性链逐位。能力行全部「既有」、零新增——判断依据:零行为变更=玩家可观测能力面零变化;能力清单零编辑(批末核对义务在 T2)。 + +**闸口径**:重闸=`tools/run_all_gates.sh` 按本批改动域选档(改动含 game/ 下非 .md 行为载体 → `--code`);所选域全绿才合并。卡内不写死闸件名单。回归措辞:里程碑卡出口跑一次全套闸;卡内修复只做出红最小单元的最窄确认;新增测试先行孤立验证再并入全套。 + +**测试削弱申报**:零条——本批零删改既有断言(grep 实核:tests 对 reload/EC8/NODE_TYPES 零引用,无断言需要迁移)。 + +**独立验收审计**:入口=批末 T2 后、合并前;报告=`reports/iter-验收审计-<日期>.md`;由没参与实现的会话或子代理执行,核对:对照表逐行断言真实存在且当轮通过、sweep 非空前置在案、零删改核对、S13 键只降不升对账。未过不合并。 + +## 9. 异常分级 + +- **L1 自救**:删除行错位一行、sweep 正则笔误、注释错字——就地改,记录进实现报告。 +- **L2 记录继续**:行号 ±5 行内漂移(grep 符号锚定位后继续)。 +- **L3 停机写报告等用户**:①实现中发现 `reload()`/`NODE_TYPES` 出现卡面未登记的第三处消费面(现状事实失实=上游缺陷,禁代裁);②删除后任一既有套件转红(零行为变更契约被破=停卡,禁就地调和);③机检键与卡片契约互斥=停卡呈报,禁自造第三条路。 + +## 10. 代拍板白名单 + +- sweep 正则具体写法与断言消息措辞(尾缀〔架构P2 Vn〕与判别词保留)。 +- 删除点上下空行/注释的整理(语句序不变)。 +- 逐卡内「孤立验证→出红最小单元→并入全套」执行顺序细节。 +超清单的决断记入实现报告「实现决定记录」节。 + +## 11. 待裁点 + +**零待裁点,开工门=U0**——两处退役/单点化方向均由审计读数+用户总判据 3(死代码不保留)+2026-11-03 会话授权导出;删除边界、单点落点、T 卡分解、验收断言由写卡期实查定死(第 3/7 节)。本卡未新增备选案。 + +## 12. 落位与可复用性预检 + +**新增文件(1 件,测试件)**: +- tests/unit/core/encapsulation_p2_sweep_test.gd——为什么不能复用 5.1 卡的 encapsulation_sweep_test.gd:两卡独立 worktree 独立实现批(合回顺序未定,并件会让扫描面归属与尾缀语义跨批纠缠);本卡 sweep 仅两组四处、体量小;扫描手法同源(源 token 扫描先例),合回后如需并件归后续纯测试维护批裁决。grep 同名零命中。 + +**新增函数/成员**:零(纯删除+一处改指——无任何新增生产函数/成员/数据件)。 + +**复用既有**:源 token 扫描手法=encapsulation_sweep_test/player_copy_sweep_test 先例;manifest 登记=run_all.gd 既有条目族;schema class_name 直引形态=config_db 域容器四先例。 + +**分层与交互面**:R2 前向边 core→data/schemas=S3 豁免面在案形态(同 config_db 持表容器方向);零新增跨域路径、零新依赖;RngService 红线零触碰;Core 零 UI 红线零触碰;数值单一事实源零触碰(零表改动)。 + +## 13. 禁为机检文本保留无效成员 + +本卡为退役/收敛类卡:删除面禁留兼容别名、转发壳、注释化残段(`set_reload_gate`/`reload`/`_reload_gate` 删除后禁以任何形态残留);词表删除后生成器禁留本地副本或镜像常量。机检键与卡片契约互斥时实现段一律停卡呈报,不得自造第三条路。 + +## 14. 实现规范预算 + +新增 .gd 仅 1 个测试件(SceneTree 脚本,全类型标注、零公开生产面)。生产代码全部落既有件,按「存量触面一查」对账(S13 默认阈值): +- **净减件**:config_db 公开 8→6、类变量 10→9;battle_orchestrator 零成员变化(两行语句删);node_map_generator 零成员变化(常量删+一处改指)。 +- **存量触面 S13 预期**:触件三件 S13 键较现场基线只降不升(净删为主);gdstyle 基线对三件零登记键,T1 现场读数即对账基线。 +- **指标例外申报**:无。 + +## 15. 拆分边界纪律 + +本卡零新拆件——三触件全部架构在册既有件,只做死代码退役与词表单点化;逐件职责语句不变(config_db=加载/校验/override/诊断门面〔reload 非其现行职责——死链随批清除〕;node_map_generator=关卡节点图生成域唯一承载〔词表消费方身份不变、定义权归 schema owner〕)。单一变化原因=封装与单一事实源(死链清零、词表归一),非阈值驱动。禁凑计数袋:本卡无成员打包面。先例=3.1+3.2 批甲案死效果通道退役(EFFECT_KINDS 摘名+分支删除,用户总判据 3 同款判法)。 diff --git a/待办清单.md b/待办清单.md index f185a3f8..cc95b5dc 100644 --- a/待办清单.md +++ b/待办清单.md @@ -20,6 +20,8 @@ **2026-11-02 写卡(2026-11-03 修订闭合)**:需求卡片 reports/需求卡片-架构审查3.1+3.2整改批-2026-11-02.md(v1.2——子代理写卡+grilling 一轮 19 条折入+godot-master 式终审 4 条折入,pipeline_gate PASS,worktree 提交 2f43b81d);11 张 T 卡估时合计 8 工作日(超 10 须特批提示在卡);能力行 10 增 5 改 1 删已入 game/tests/README.md。 +**2026-11-03 P2 部分(5.1 封装+5.2 文档漂移+5.3 词表)推进**:5.1 设计闭合+已写卡——处置记录落 arch51-docs worktree、需求卡片 v1.1(godot-master 终审七项折入,pipeline_gate PASS)落 arch51-card worktree,两件随各自合回落 master 后互见;5.2 文档漂移四处归真已落档(architecture.md v1.32——HeroLedger 行拆件四件补登记/冻结计数摘除/MetaProgression 补登记行;EC8 GDD 侧规格退役=数据配置.md v1.3+战斗结算.md v1.7+棋盘生成.md v1.3,arch51-docs worktree 提交 63fc3e74,文档域闸全绿);5.3+EC8 代码面已写卡——凭据=reports/需求卡片-架构审查P2代码面批-2026-11-03.md v1.0(本条目所在 master 基点 ab5d75a2 的 archp2-card worktree,零待裁点,估时 0.5 工作日,排序在 5.1 卡后);**未闭合余项收窄**=闸面缺口(S1/S2/S9/S13 扫描面、S8 目录域)、S13 三处豁免存废、零测试点名四件、presentation 层私取面约 227 行(另开设计讨论)。 + **改动面**:文档+游戏代码+工具代码 **状态**:文档设计已闭合+已写卡+已编迭代 50