Files
gplan-2/design/engineering/architecture/architecture.md
T

378 lines
47 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Dungeon Sweeper — 总体架构文档
## 文档状态
- 版本:1.9
- 最近更新:2026-10-21(迭代 32 卡②反哺点写入——effect_engine 行与战斗域装配节改无状态化 ctx 形态、架构原则新增「系统无状态」条;2026-10-21 用户裁)
- 引擎:Godot 4.7.2-stable(GDScript 单语言;2026-09-07 锁定)
- 评审模式:solo(`review-mode.txt`,2026-09-12 用户拍板——TD/LP 门禁按 solo 跳过,用户授权架构产出自主推进、迭代期回调)
- 覆盖 GDD:现行全集——`design/gdd/` 顶层 00–08 共 9 件 + `systems/` 五域 25 件(排雷循环 4 / 战斗循环 5 / 冒险循环 5 / 跨局循环 5 / 表现与支撑 6)+ `ux/` 8 件;原英文命名 12 份系统 GDD 已全部迁入中文域目录,原「未设计」预留(A5 扫雷秘宝 / C1–C4 / B5 / D3–D6)均已立项成文
- 事实源地位:本文是架构事实的唯一来源——分层/所有权/数据流/API 边界/测试与质量域均以本文为准;历史决策沿革查 git commit log,不另设决策文档体系
- 实现实证:`game/`(2026-09-10 起开发,**现为完整游戏开发版本,已非垂直切片**;测试层级=冒烟/单元/集成/系统四级+UI 探针与渲染 golden(2026-10-22 用户裁,测试术语与层级重构批),闸机按改动域分跑在役)——本文档的分层/所有权/数据流均经实现验证,非纯纸面设计
- 技术总监签核:2026-09-12 — 有条件通过(原条件「决策记录须于正式工程骨架前定稿」已满足:骨架已成、沿革在 git 历史可查;`.claude/docs/director-gates.md` 缺失已登记技术债)
- 主程序可行性:跳过 — solo 模式
---
## 引擎知识缺口摘要
- **风险等级:MEDIUM**(2026-09-12 `/setup-engine refresh` 后由 HIGH 降级)。4.5→4.7 官方迁移指南已逐条核实并入 `design/engineering/engine-reference/godot/breaking-changes.md` 与 `deprecated-apis.md`;**结论:无一条破坏 GDD 已锁架构契约**(autoload 体系 / .tres 单一事实源 / Callable 信号 / int64 二补数 / headless SceneTree 协议均不受影响)。
- 写码纪律不变:不确定的 API 一律查 `docs.godotengine.org/en/4.7/` 核实后再用;4.8(dev 阶段)稳定版发布后跑 `/setup-engine refresh`。
- 三类必须入编码纪律的引擎事实(详见 `design/engineering/engine-reference/godot/current-best-practices.md`):
1. **GDScript 4.7 两条语义变化**:打包数组元素赋值不再触发属性 setter;类型化返回的方法覆盖必须显式 `return`。
2. **新项目默认值已变**:stretch mode `canvas_items` / aspect `expand`(4.7);Windows 渲染驱动 D3D12(4.6,仅 Forward+ 线)——创建 project.godot 后逐项核对。
3. `Resource.duplicate(true)` 深复制不再覆盖外部子资源——D2 表资源复制语义注意。
- 残余风险敞口:modules/ 分域参考未建(按实现期需要建,非阻塞);UI/渲染域(D1/B5)为 MEDIUM 风险集中地——渲染器与窗口基座已定(gl_compatibility + 1280×800,2026-09-12),采纳引擎增量前对照文档核实。
---
## 系统分层图
20 系统按 `design/gdd/02-系统清单.md` 依赖分层表映射到标准五层。实现已验证该分层(core/ 纯逻辑零 UI 依赖 headless 可跑、presentation/ 组合根模式)。
```
┌────────────────────────────────────────────────────────────┐
│ 呈现层 │
│ D1 HUD 与界面框架 (MVP) · B5 战斗表现 │
│ D4 音频 (Beta) · D5 教学引导 (Beta) │
├────────────────────────────────────────────────────────────┤
│ 功能层 │
│ B1 战斗结算编排 (MVP) · C1 关卡节点地图 (lite 已实装) │
│ C2 冒险结构 · C3 难度曲线 · C4 元进度 (Alpha) │
├────────────────────────────────────────────────────────────┤
│ 核心层 │
│ A1 扫雷棋盘生成 · A2 排雷玩法规则 · B2 敌人系统 │
│ B4 地图战斗资源 · A5 扫雷秘宝 │
├────────────────────────────────────────────────────────────┤
│ 基础层 │
│ D2 数据配置与数值表 · A3 行动经济 · A4 地形变异 │
│ B3 增益/状态系统 · D3 存档序列化 (Alpha) · D6 设置/本地化│
├────────────────────────────────────────────────────────────┤
│ 平台层 │
│ Godot 4.7.2 引擎 API 面(GDScript / Resource / │
│ SceneTree / Control / InputEvent)——无游戏系统 │
└────────────────────────────────────────────────────────────┘
```
> 层名对照:基础层=Foundation、核心层=Core、功能层=Feature、呈现层=Presentation、平台层=Platform——本文一律用中文名;跨文档与代码目录仍见英文名(`game/core/`、`game/presentation/` 等目录名不改)。
| 系统 | 层 | 里程碑 | headless 约束 | 引擎风险域 |
|---|---|---|---|---|
| D2 数据配置 | 基础层 | MVP | ✅ 完整可跑 | LOW(Resource/.tres 基线稳定) |
| A3 行动经济 | 基础层 | MVP | ✅ 完整可跑 | LOW(纯逻辑) |
| A4 地形变异 | 基础层 | MVP | ✅ 完整可跑 | LOW(纯逻辑) |
| B3 状态系统 | 基础层 | MVP | ✅ 完整可跑 | LOW(RefCounted 纯逻辑) |
| A1 棋盘生成 | 核心层 | MVP | ✅ 完整可跑 | LOW(纯逻辑) |
| A2 排雷规则 | 核心层 | MVP | ✅ 完整可跑 | LOW(零表读取零 UI) |
| B2 敌人系统 | 核心层 | MVP | ✅ 完整可跑 | LOW(纯逻辑) |
| B4 地图战斗资源 | 核心层 | MVP | ✅ 完整可跑 | LOW(纯逻辑) |
| B1 战斗结算编排 | 功能层 | MVP | ✅ 完整可跑(禁 await) | LOW(纯逻辑) |
| C1 关卡节点地图 | 功能层 | MVP(切片期实装) | ✅(切片 level_runner 先例) | LOW |
| C2 冒险结构 | 功能层 | MVP(切片期实装) | ✅ | LOW |
| C3 难度曲线 | 功能层 | MVP(切片期实装) | ✅ | LOW |
| C4 元进度 | 功能层 | Alpha | ✅ | LOW |
| D1 HUD | 呈现层 | MVP | ❌(UI 层——场景级探针测试承载) | **MEDIUM**(Control/Input/文本域) |
| B5 战斗表现 | 呈现层 | 切片后立项(未实装,前置战斗表现美术测试) | ❌ | **MEDIUM**(Animation/Tween/渲染) |
| D4 音频 / D5 教学 | 呈现层 | Beta(2026-10-13 Alpha 版本标准裁:与游戏内容无关者一律排 Beta) | 部分 | LOW-MEDIUM |
| D3 存档序列化 | 基础层 | Alpha | ✅ | LOW |
| D6 设置/本地化 | 基础层 | 完整愿景 | ✅ | LOW |
**MVP 关键路径**(实现已验证):D2 → A3/A4/B3 → A1 → A2 → B2/B4 → B1 → D1-lite。
**依赖分层与唯一回边**:A2 只外发三事件(cell_revealed / flag_judged / round_end),B4/B1 订阅后回调——A2 不依赖任何下游(TD-SYSTEM-BOUNDARY 裁决,全项目唯一允许回边)。
---
## 模块归属
> 命名遵循 `design/engineering/code-conventions.md`:领域命名、禁 ID 前缀(文件头注不写文档链接——「实现 GDD:xxx」一类已废止,代码↔设计追溯由 GDD 文档承担)。切片已按此规范完成领域命名批。
### 基础层
| 模块 | 独占职责 | 对外暴露 | 消费依赖 | 引擎 API |
|---|---|---|---|---|
| **ConfigDB**(autoload,D2) | 全部玩法数值表(`data/tables/*.tres` + `data/schemas/*.gd`);SCHEMA_VERSION;加载/校验/override/诊断状态机 | 类型化属性读取;`load_tables(root, collect_only)`;`resolve()`(R1 floor);debug override;`set_reload_gate()`;诊断收集器 | 无(基础层顶点) | Resource/.tres 加载、autoload 生命周期——LOW |
| **RngService**(autoload,D2) | master_seed、各流 scope 计数器(封闭流:board_gen / reward_roll;增流走 P1 评审) | `set_master_seed()`(唯一调用方 C2);`open_stream(stream)` 有状态门面;`derive_at(stream, scope)` 纯函数;只读计数器 | ConfigDB(无) | 无——纯逻辑 |
| **action_economy**(A3) | AP/RAP 账本、last_round_end、轮次相位机 {Idle, Active, Waiting}、结束仲裁 | 8 API 全布尔面:notify_round_start / request_dig / request_flag_place / request_flag_pull / request_stop / request_refresh / notify_settlement_done / notify_combat_end;ap/rap/phase 只读 | ConfigDB(ActionEconomyTable);B1 回发 next_round_mode/battle_over | 无 |
| **variation 定义**(A4) | VariationTable schema(现行 6 行:六 region——贫矿脉 global 行 2026-10-16 用户令屏蔽删行,global 型机制代码保留)与 F1 候选池门控谓词 | `variant_pool(level_index, board_type, node_type="")`(门控三维:unlock+board_types+节点身份——global 行仅 boss/elite 入池,缺省跳过零扰动);`global_variant_row(level_index, board_type, node_type)`(全局型单行决议访问器) | ConfigDB(VariationTable) | 无 |
| **status_container**(B3) | 状态实例容器(战斗域生命周期、跨轮跨图延续) | 5 API:notify_battle_start / apply_effect / query_active / decay_round / notify_battle_end | ConfigDB(StatusEffectTable) | 无(RefCounted) |
| **save_system**(D3,Alpha;iter27 已升格 autoload「SaveManager」) | 存档格式与版本比较 | (契约规范源:`../../gdd/systems/表现与支撑/存档序列化.md`——契约锚:SCHEMA_VERSION + master_seed + 各流 scope 计数器快照,须在无正在执行中的 open_stream 实例时切出) | ConfigDB、RngService 只读计数器 | FileAccess——LOW |
| **settings/localization**(D6,愿景) | 设置项、翻译数据 | (契约规范源:`../../gdd/systems/表现与支撑/设置与本地化.md`) | ConfigDB | 无 |
### 核心层
| 模块 | 独占职责 | 对外暴露 | 消费依赖 | 引擎 API |
|---|---|---|---|---|
| **board_generator**(A1) | 生成算法(五阶段管线)、BoardGenTable 回填、生成期指标集、合法性谓词(clearable / R₀≠S / min_safe)、可推理率度量(metric_version);生成姿态 = MVP 同步生成 + 加载幕(切片实证 10×10/12×12 同步可接受,WorkerThread 留扩展) | `generate(L, D, rng) -> Board`;度量独立入口×3(推理器 / F3 度量 / 合法性谓词——独立纯函数、同一实现) | ConfigDB(BoardGenTable/VariationTable);board_gen 流(一次 open_stream = 一张图);dig_ap_cost 只读 | 无 |
| **minesweeper_rules**(A2) | 棋盘状态(已开集 O / 封印集 G / 小人位)、三事件面、批次仲裁、install 四不变式 | `install_board(board)`;`settle_batch(intents)`(唯一提交入口);try_dig / try_flag_place / try_flag_pull / try_move(便捷形);`compute_move_path(cell)` 只读;`retire_board()`;三源拒绝(board_face / resource_face / phase)+ sub_reason 封闭枚举 | A1 产物(Board class_name 数据契约);A3 try_spend / last_round_end / 相位 | 无(零表读取、零 UI——切片实证) |
| **unit_container**(B2) | hero/enemy 单位实例(hp/atk/实例池:池快照+冷却+摇定动作+保底计数)、行值快照 | spawn / query_alive / rollable_skills / special_skills / set_pending_action / pending_action / basic_streak / commit_action / tick_cooldowns / apply_damage / heal / default_target / ambush_grant_plan / despawn_all(2026-09-16 敌人技能池批:query_beat/query_attack/advance 随行为环退役) | ConfigDB(EnemyTable/SkillTable/HeroTable) | 无 |
| **reward_economy**(B4) | 格面资源身份映射(install 期预分配、Ready 只读、换图映射消亡)、极性路由字典面((类型, 极性)→ 字典行查询;路由执行归 B1 授予段)、F6 当量供给投影 | 封闭 API:roll_board / query_identity / query_full_snapshot / grant / grant_clear / retire_mapping / polarity_row / equivalence_supply / phase / weighted_pick;另有 is_mapped 静默布尔投影(批量工具用) | ConfigDB(RewardTable);reward_roll 流(scope = 每次 install 批) | 无 |
| **helper_items**(A5,切片已实装秘宝域) | HelperItemTable、探测显影语义 | (契约规范源:`../../gdd/systems/跨局循环/秘宝.md`——桥接位:A2 查询接口 + A4 counter_item_ids) | A2 / A4 / B4 | 无 |
### 功能层
| 模块 | 独占职责 | 对外暴露 | 消费依赖 | 引擎 API |
|---|---|---|---|---|
| **battle_orchestrator**(B1) | 段序骨架(七段结构冻结)、轮 facts 缓冲、可回放步骤流、[明细行协议](../../gdd/systems/战斗循环/战斗结算.md#明细流水每一行都能指回你刚才的哪一步棋)(15 类行 + 字段分层)、条款③⑤闭合对账、**战斗域全部跨系统调用权**、效果引擎宿主(每战 rebuild;round/battle 桶为编排器自有字典、经 EffectContext 引用挂载)+ 树规则挂点施加面(posture 窗/sense 限次/守侧 seal_missed 发射/聚乘算入账前) | `begin_battle(encounter)`;窗口/刷新意图提交面(扮演 D1);`level_clear()`;步骤流(输出契约) | B2/B3/B4 全调用面(**唯一调用方**);A3 request_refresh 代理 + 回发;A2 install/retire + 三事件订阅;A1 generate(attempt 非 scope 事件);D2 SettlementTable + set_reload_gate | 无(零随机、禁 await——切片 88 冒烟实证可回放) |
| **effect_engine**(核心层——内容数据驱动扩展批 iter17 建域) | 零运行时可变状态的系统(见「架构原则」条 8):事件/事实/效果类型/算子四词表封闭(迭代 21 T3 扩签:EVENTS 18→19 +seal_missed 标错判定、FACTS +battle_index 关卡域战斗序)+ 树规则合成订阅六键(posture 每关首轮窗/sense 两组限次 counter 闸·adv_ 前缀走冒险桶跨战斗持久) | rebuild(每战重建订阅表)/`dispatch(ctx, event, payload, facts)`/`validate_trigger_row` + 静态计数口 `counter`·`counter_add`·`counter_spend`·`bucket_of`·`counter_id_legal`(计数器读写只经 EffectContext 引用束,无导出/灌入接口) | ConfigDB(feats/treasure 行集)、EffectContext(四桶引用由宿主持有:round/battle 桶归编排器、level 桶归关卡域、adventure 桶归 RunLedger) | 无(零随机全确定) |
| **level_runner**(C1-lite,切片已建) | 关卡域生命周期(节点链推进、共享 B4 + HP 携带、关卡末 level_clear) | 节点推进接口;LevelTable(`level.tres`——节点 enum {battle,reward,rest,boss}、末节点必须 Boss、ConfigDB 跨表校验⑧) | B1 begin_battle、B4 grant_node_active、ConfigDB LevelTable | 无 |
| **run_structure**(C2) | 冒险/关卡序列、失败重开、**master_seed 唯一接线方** | (契约规范源:`../../gdd/systems/冒险循环/冒险结构.md`) | RngService.set_master_seed、C3/D2 | 无 |
| **difficulty**(C3) | DifficultyTable 回填、全部曲线数值调参所有权、战斗期望表(切片 monte_carlo 为工具原型) | 调参输出(经 D2 R1 解析/编排器传递,禁反向调用生成) | ConfigDB、B1 对账输出(调参约束清单)、A1 报告 C | 无 |
| **meta_progression**(C4,Alpha) | MetaTable、钥石账本、天赋树域(MetaTreeTable 12 节点 v0.8——Fork 一节点双态/row 字段退役/RULE_KEYS 六键/彩蛋特化觉醒,迭代 21 T1 换代)+ 同调位槽位判定(树点亮数单源——T4 槽位收编) | tree_can_buy/tree_buy/tree_buy_fork/tree_toggle_fork(写口唯一)、hero_override 注入(树淬炼 flat+锻造路线加值位预留 0)、tree_rule_keys | D3、C2、ConfigDB | 无 |
### 战斗域装配现状(迭代 27——2026-10-17 用户裁写入)
- **结算五段**:B1 编排器的每轮结算序列拆为 `game/core/settlement/` 五个段类——GrantSegment(①授予段,含封印判定与 counter/grant 助手单点)→ AuraSegment(②增益/减益段)→ CombatSegment(③战斗段)→ DecaySegment(④衰减段)→ VerdictSegment(⑤判定段,返回裁定,终局早退语义留 B1)。段序骨架冻结于 `SettlementTable.segment_order` 语义,B1 退为段序编排+接线;段类可直接 `new()` 单测(`settle_segments_test` 在役)。
- **RunLedger 四账**:`game/core/run_ledger.gd` 单类持四本共享账——同调充能账/真视使用计数/冒险域计数器/统一冒险加算区。所有权:AdventureRunner 开局构造、全程唯一宿主;LevelRunner 经 `set_run_ledger` 下传装配 encounter;战斗侧(B1)经 `encounter["ledger"]` 拿引用、只走 read/append 原语族。审计 P1-4「共享可变字典跨三层三处可写」由「函数签名上不可见的共享引用」换成签名可见的显式类。冒险桶计数器无导出/灌入时点:EffectContext 持 `run_ledger.adventure_counters` 的同一字典引用,引擎静态计数口就地直写,跨战持久随 RunLedger 生灭(2026-10-21 迭代 32 卡②无状态化写入)。
### 呈现层
| 模块 | 独占职责 | 对外暴露 | 消费依赖 | 引擎 API |
|---|---|---|---|---|
| **D1 HUD**(呈现面拆分持续换代:组合根 main.gd + 三屏壳(MenuScreen/CampScreen/AdventureScreen)+ views/ 视图单元(现行承载面见「呈现层装配与会话生命周期」节;早期 9 单元清单与 LevelStripView 已随场景换代退役);营地覆盖层=四柜台并排〔树淬炼主界面/锻造工坊·秘宝匣钥匙门/图鉴常开——迭代 21 T6 程序占位重排〕) | 全部 Control/CanvasLayer(例外:BoardView 棋盘本体与 BattleStageView 站桩本体 = Control 壳 + SubViewportContainer + SubViewport + Node2D 世界〔BoardWorld/CellUnit;StageWorld/StandeeBody——B 区 slot_row 伴随件留壳层〕,探针契约面不变——棋盘 Node2D 迁移批 Phase A 2026-09-23 / 战斗舞台 Phase B 2026-09-26)、输入→意图翻译(**唯一提交路径 = settle_batch,不直调 A3**)、呈现义务状态记录(A2×6 / B2×4 / B3×4 / B4×5 / B1×3) | 视图单元接口(信号外发、setter 只读注入) | A2 compute_move_path / ActionOutcome;A3 ap/rap;B1 步骤流行协议(数据源);ConfigDB display_name | **MEDIUM**:Control / CanvasLayer / draw_* / InputEvent / RichTextLabel——对照 breaking-changes.md 4.5–4.7 条目(CanvasItem 线条无抗锯齿羽化、设备 ID 常量、RichTextLabel 图片参数两轮变化) |
| **battle_presentation**(B5,垂直切片后) | 结算动画 / 伤害数字 / 战斗舞台 | (契约规范源:`../../gdd/systems/战斗循环/战斗表现.md`——前置「战斗表现美术测试」锁双舞台陷阱) | B1 步骤流(回放脚本源)、D1 | **MEDIUM**:AnimationPlayer(String→StringName 变更)/ Tween |
| **audio**(D4,Alpha) | 音频挂点 | (挂点 = B1 明细行类型流;负反馈聚合——单结算至多一次) | B1 流水 | AudioStreamPlayer(4.7 area_mask 默认 1→0 注意) |
| **tutorial**(D5,Alpha) | 教学条目 | (口径来源:A2/A3/B3/B1 各教学条目) | 各上游 | 无 |
**依赖单向性**:上层可消费下层,禁止反向(C3 禁调用 A1 生成、D1 不直调 A3、A2/B3/B4 零相互直调)。全项目唯一回边 = A2 事件订阅面。
---
## 呈现层装配与会话生命周期(迭代 27/28 完成反哺——2026-10-17 用户裁按推荐案写入)
### 三屏壳与组合根句柄面
- 呈现场景拆为三屏壳:MenuScreen(开始菜单屏)/CampScreen(营地屏)/AdventureScreen(冒险屏——内含关卡地图与战斗两容器)。
- 屏成员经组合根 main.gd 一级句柄暴露(探针挂载假设 `main.X` 路径零迁移);局态一律住 RunScope 节点,禁在屏/视图侧持有局态引用。
### 视觉层装配合同
- **树序 = 登记序 = z 序**,同源派生;层序唯一事实源 = `main.gd` 的 `LAYER_CONTRACT` 常量表(现行 17 项,kind 五类:shell=屏壳〔成员随壳不占独立树位〕/modal=模态层〔入登记册,tags 随登记〕/state=全屏态/node=非视觉节点/float=不注册 ModalStack 的最顶浮层〔任何 UI 打开都不遮挡它〕)。
- 全仓唯一落位口 = `_apply_layer_contract()`(装配尾统一排序+登记);散落 `move_child` 由冒烟 V1d 源码断言判红;**改层序只改合同表**。
- 具体层清单不复制进本文(双写失同步禁令)——查现行 17 项直接读 `main.gd`。
### 会话生命周期(RunScope)
- `run_scope.gd` = 纯状态承载 Node:零信号连接、零视图构建、零核心写调用(连接只在组合根,组合根经 `run_scope.X` 读写)。
- 会话更替机制:`_begin_session()` 新建会话节点挂树、旧会话节点**整节点 `queue_free()`**——无独立收束函数,跨局字段清理靠节点释放机制(原手工复位清单随其消亡,新增跨局字段零新增泄漏点);`_ready` 即建闲时会话,`run_scope` 永非 null。
- **存活性矩阵**(九阶段 × 五引用面,2026-10-17 用户裁认账阶段划分;执行判据=冒烟 V3a–V3i。计划书原十阶段中「开局停点」与「地图选路」在现行流程同为关卡画面停点态、无可观测中间态,合并为一处断言):
| 阶段 | run_scope | adventure | runner | settlement |
|---|---|---|---|---|
| ① 闲时 | 在树(闲时会话) | null | null | null |
| ② 开局停点 | 在树 | alive | alive | null |
| ③ 战斗中 | 在树 | alive | alive | alive |
| ④ 结算后(胜利停点)/⑤ 选路页 | 在树 | alive | alive | both |
| ⑥ 终局面 | 在树 | alive | alive | null |
| ⑦ 回菜单收束 | 新闲时会话即刻在树(旧会话已释放——无真空窗) | null | null | null |
| ⑧ 各模态开合后(设置/生涯/营地/调试) | 闲时会话零扰动 | null | null | null |
| ⑨ 两连局+续玩断点 | 换全新会话在树 | alive | both | both |
- 三态记号沿用冒烟参数:**alive**=应有实例、**null**=必须缺位(实测非空判红)、**both**=按分支可空可活(如胜停点后走向选路或直接终局)。对象有值但已失效一律判「悬挂」红。
- 第五引用面=四持句柄件(`_treasure_ui`/`_bonus`/`_camp_pres`/`_modal_flow`,另有 `_row_pacer`):其会话取值 Callable 与 `run_scope` 成员**逐面同源比对**(回调悬挂=两值不等即红),会话更替零残留由矩阵每阶段顺带铁证。
### 模态编排(ModalFlow/ModalStack)
- `modal_flow.gd` = 模态编排纯逻辑类(依赖仅 ModalStack + 查询 Callable,可直接 `new()` 单测):开合编排(遮挡记账单口 + T17 演播后排窗挂起)/棋盘输入锁谓词/角标置灰谓词三职责。
- 互斥排除语义随层登记(`register(node, tags)`):`debug_overlay=["non_locking"]`、`level_screen=["screen_state"]`,其余层零标签——原调用点排除式条件拼装已消亡。
---
## 测试与质量域
> 定位:本节为测试域(本地闸、探针、静态扫描等横切关注点)的**事实源**。仓库无远端、无 CI——本地闸是唯一验收门禁,判定严密性即全仓质量下限。
### 模块归属
| 模块 | 载体 | 独占职责 | 对外暴露 | 判定口径 |
|---|---|---|---|---|
| **run_smoke**(冒烟测试运行器) | `tools/run_smoke.py` | 冒烟测试总入口与判定权:headless 以项目运行目标拉起 `res://tests/smoke_boot.tscn`(极小启动场景——autoload 在位、配置表全载、主屏实例化,零逻辑判定)+ 三闸判定 | 进程退出码(0=PASS / 1=FAIL) | 三闸齐备、判定无洞:①退出码 = 0;②摘要行「[smoke] 摘要:N 项检查,0 项失败」在案且失败数为 0;③输出扫 `SCRIPT ERROR` / `Parse Error` 标记行。外部 wall-clock 超时在位(超时 = FAIL) |
| **run_system_test**(系统测试运行器) | `tools/run_system_test.py` | 系统测试总入口:headless 跑真实玩法路径断言面(宿主=`res://tests/system_test.gd`)+ 三闸判定(口径同 run_smoke,摘要行兼容两种宿主格式) | 进程退出码(0=PASS / 1=FAIL) | 三闸齐备(同 run_smoke:退出码/摘要失败数/脚本错误扫描;wall-clock 超时在位) |
| **run_all**(单元与集成测试) | `game/tests/run_all.gd` | 40 套统一入口(39 单元+1 集成,2026-10-22 实数):套件 manifest 逐条「套件 → 期望退出码」,致命类 expect=1 独立子进程实跑;`negative` 字段标负面套件(仅豁免错误扫描一闸) | 逐套件结果 + 汇总退出码(任一套件失败 quit(1)) | 套件级退出码协议在位;三硬闸齐备(入口内扫子套件输出 + 编排层扫 `unit.log`;`Kit.finish` 零断言返回专用码 2)。子进程输出须经系统命令解释器重定向落盘再读——`OS.execute` 的输出管道在本机恒空 |
| **probe_gate**(场景探针) | `tools/probe_gate.sh` | headless 场景探针段编排:默认段 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;孤儿 Godot 预清 + 批末残留清点(必须 0) | 段级 FAIL 输出 + 汇总退出码 | 每段 timeout 守卫在位(挂死 124/137 = FAIL,不静默);判定统一走 `verdict` 函数——退出码为唯一权威判据,PASS 串降级为附加判据,逐段跑 `tools/error_scan.py` |
| **render_gate**(视觉 golden) | `tools/render_gate.sh` | 窗口化渲染闸:①shot_probe 七屏截图 → shot_checker A-D 语义断言;②fx_shot_probe / board_shot_probe 取证(超时/零字节/文件缺失任一 = FAIL);③棋盘 golden 逐像素容差比对(差 ≤16 / changed ≤2%,provisional)+ 菜单 golden;④批末孤儿残留清零 | 段级 FAIL 输出 + 汇总退出码 | 查退出码在位(每段 timeout 守卫 + 退出码/取证文件双检);**SCRIPT ERROR 扫描缺失**;断言数下限不适用(判定主体 = golden 容差与取证文件存在性,非断言计数) |
| **static_scan**(静态扫描域) | `game/tests/static_scan.sh` | 静态扫描域 S1–S10 可执行载体(grep 规则 + `tools/audit_type_hints.py`〔S9〕+ `tools/audit_file_headers.py`〔S10〕) | fail 聚合退出码(任一硬失败规则命中即 exit 1) | 查退出码在位;SCRIPT ERROR 扫描与断言数下限不适用(逐规则命中即红,无运行时错误面与断言计数);S3 现为 warning 级、不参与 fail 判定(见下表) |
### 改动域划分(2026-10-17 用户裁「代码批只跑代码闸、文档批只跑文档闸」)
| 域 | 闸 | 本批改动落在这些路径即属该域 |
|---|---|---|
| **代码域** | run_smoke、run_system_test、run_all、probe_gate `--click`、probe_gate `--full`、render_gate、static_scan、回放确定性对拍(条件件) | **唯一触发=`game/`**(游戏工程代码、测试、探针、场景、数据表)。2026-10-18 用户裁「跨领域执法禁绝」(提交 `7bdf53e3`)后,原 `tools/`、`artwork/` 两前缀不再把改动拉进代码域 |
| **文档域** | gdd_lint、doc_link_audit、doc_term_audit、流水线闸 | 一切非 `game/` 的路径:`design/`、根规则文件(`AGENTS.md`/`roadmap.md`/`待办清单.md`/`体验验证清单.md`)、`tools/` 工具脚本、`.zcode/` 配置、`sim-data/`、`reports/` |
| **两域都含** | repo_structure_audit(熵增闸:顶层目录/根文件/图像白名单/退役路径/design 子目录五查——文档批新增或挪动 `.md` 同样会绊它;纯文本扫描秒级) | — |
口径三条:**域划分的唯一出处是 `tools/run_all_gates.sh`**(`--code`/`--docs`/不带参数=全量),本表是它的现状登记、不是第二份清单;改闸件本身或一次改动跨两域 → 跑全量档(§6.2 共享件例外);合回闸按 merge diff 路径推出应验的域,再校验回执的 `domain` 字段与新增红。代码域跑前先过**素材齐盘预检**——`game/assets/art/**` 与一切 `*.import` 边车都不入 git(2026-09-29 裁定),worktree 冷检出必空盘,空盘态冒烟 V1 成片假红、渲染闸更是一段 golden 都不比。
### 三条判定硬闸现行状态
| 硬闸 | run_smoke | run_system_test | run_all | probe_gate | render_gate | static_scan |
|---|---|---|---|---|---|---|
| **退出码优先** | 已落实(闸①) | 已落实(闸①,口径同 run_smoke) | 已落实(套件 manifest expect 协议) | 已落实(`verdict` 函数逐段判退出码,PASS 串不作判据) | 已落实(段级退出码 + 取证双检) | 已落实(fail 聚合退出) |
| **SCRIPT ERROR 扫描** | 已落实(闸③,外部扫描——GDScript 无脚本错误陷阱 API,闸设在外部包装) | 已落实(闸③,标记清单与 run_smoke 同源) | 已落实(入口内扫子套件输出;子进程的 stdout/stderr 须先落盘——`OS.execute` 管道在本机恒空) | 已落实(逐探针段 `tools/error_scan.py`,标记与 run_smoke 同源) | **缺失**(本批未收——判定主体是 golden 容差与取证存在性;登记待办清单) | 不适用(静态域无运行时错误面) |
| **断言数下限** | 无独立下限(闸②摘要行必须在案,防「跑一半仍 PASS」;脚本错误吞断言路径由闸③兜住) | 同 run_smoke(过渡期宿主摘要行必须在案) | 已落实(`Kit.finish` 零断言返回专用退出码 2——与「断言失败=1」区分,防致命类套件的 expect 协议放过) | 已落实(退出码 0 但无该探针签名标记亦判红——防静默退出) | 不适用(golden 容差 + 取证存在性判定) | 不适用(逐规则命中判定;另有扫描面为空即判红的零命中自检) |
背景事实(run_smoke 头注在案):GDScript 运行时脚本错误不改进程退出码、不计入冒烟失败数、且静默中断所在函数剩余断言——2026-09-19 状态记录 83 实证「309 项 0 失败」实为断言未跑全。这是 SCRIPT ERROR 扫描必须存在于判定层的原因。
### 静态扫描域 S1–S8 承接清单
静态扫描域规则(2026-09-12 立,沿革见 git commit log;下表为现行事实登记):
| # | 规则 | 状态 |
|---|---|---|
| S1 | 玩法代码禁 `randomize()`、自建 `RandomNumberGenerator`(D2 Rule 5) | **在位**(硬失败;扫描面 game/core + game/presentation) |
| S2 | 禁全局随机函数 `randi()` / `randf()` / `randf_range()`——全局 RNG 绕开 RngService(specialist 补登) | **在位**(与 S1 同段硬失败;实例方法 `.randi()` 排除、`rng-seed-exempt` 豁免注记在案) |
| S3 | core/ 禁 ConfigDB 外 data 表加载(`load(` / `preload(` / `ResourceLoader.load`;schema class_name 直引豁免)(D2 Rule 2) | **在位**(warning 级——class_name 直引误报需人工复核;路径已由裸 `core` 修正为 `game/core`,此前恒零命中静默空转;豁免 config_db.gd 自身=数值单一事实源的正主) |
| S4 | core/ 禁 `extends Control/Node2D`、禁 `.tscn` preload(D2 Rule 7) | **在位**(硬失败) |
| S5 | core/ 禁裸引用 autoload 全局标识符(`ConfigDB` / `RngService` 直接写 = --script 模式 parse error)——构造注入 only(specialist 升格) | **在位**(硬失败;形态=标识符后紧跟 `.` 的成员访问,排除注释行与字符串字面量) |
| S6 | core↔core 信号连接只许方法 Callable(禁 lambda 捕获 self);发射者禁持有订阅者反向引用 | **未落地**(脚本 TODO 注记在案) |
| S7 | B1 编排唯一性:B2/B3/B4 API 符号命中文件 ⊆ B1 文件集;A2/B3/B4 零相互直调(B1 AC-43) | **未落地**(脚本 TODO 注记在案) |
| S8 | 结算路径 `await` 零命中(B1 结算/编排文件集);字面量扫描 = warning 级 + 人工三要素复核(D2 AC-14 口径) | **未落地**(脚本 TODO 注记在案) |
域外扩充两件(均硬失败在位):**S9** 类型闸(`tools/audit_type_hints.py`,迭代 27 T5——产品码无类型容器/有值返回缺类型/参数缺类型);**S10** 文件头闸(`tools/audit_file_headers.py`——头注 ≤8 行 + 日期/变更叙事黑名单)。
### 三层承载与判定原则
测试分标准四级+UI 探针(2026-10-22 用户裁,测试术语与层级重构批),各有在册承载与入闸方式(细目见 `game/tests/README.md`):
| 层 | 判什么 | 承载 | 入闸 |
|---|---|---|---|
| 冒烟测试 | 这版活着吗(零逻辑判定) | `game/tests/smoke_boot.tscn/.gd` | `run_smoke.py`(闸 00) |
| 单元测试 | 最单元的逻辑代码对不对 | `game/tests/unit/` | `run_all.gd`(闸 02) |
| 集成测试 | 跨系统闭环对不对 | `game/tests/integration/` | 同上(同一入口同一协议) |
| 系统测试 | 真实玩法路径断言面 | `game/tests/system_test.gd` | `run_system_test.py`(闸 01) |
| UI 探针+渲染 golden | 场景切换与观感 | `game/probe/*.tscn` 探针 | `probe_gate.sh`(闸 03/04)、`render_gate.sh`(闸 05) |
**判定原则**:验收不能只是「跑一遍没崩」。三硬闸(退出码/脚本错误扫描/断言数下限)是判定的底线,
缺一即判定有洞;「日志里写着 PASS」不作判据。另有两类静默失效必须机制性防范——规则扫描面为空
(路径写错即恒零命中恒绿)与子进程输出丢失(本机 `OS.execute` 管道恒空),两者都以显式自检拦住。
### 依赖约束
测试域禁止反向依赖呈现层具体实现。五闸及其调用的探针场景、审计脚本只允许依赖两类边界:
1. **autoload 边界**——ConfigDB / RngService 的公开面(--script 模式不加载 autoload 且不注册全局标识符,测试文件自带显式实例化夹具);
2. **场景契约**——探针场景的信号外发面与视图单元接口(信号外发、setter 只读注入),禁直引呈现层实现内部(如 UiKit 工厂内部状态、BoardView 绘制细节)。
测试域是所有层的消费方,进入方式限于上述两类边界;除此之外的依赖方向一律与「模块归属」节依赖单向性同规。
### 事实源声明
本节为测试域(测试载体、判定口径、静态扫描域)的事实源。新增违规案例仍须先补 static_scan 规则再修码(code-conventions 缺陷-规范对照表纪律)。
---
## 数据流
### 1. 帧更新路径(2D 回合制:无逐帧玩法逻辑)
```
Input(鼠标)→ D1 输入翻译 → 意图对象 → A2.settle_batch(唯一提交入口)
→ A3.try_spend(原子扣减)→ A2 棋盘效果(挖/连锁/封印/移动)→ 三事件外发
→ [棋盘渲染:D1 BoardView 按事件增量重绘;无事件帧 = 静态 + 动效]
→ 轮次结束 → A3 Waiting → B1 结算编排(段序七段)→ 明细步骤流 → D1 结算屏逐行呈现
```
- 回合制下每帧只做:输入采样、呈现刷新、动效推进——**玩法状态只在意图事务内变更**(单意图帧输入收集:stop 点击终结当帧)。
- 无跨线程玩法数据流(Godot 主线程假设,D2 EC13);A1 生成若引入 WorkerThread,join 必须先于任何快照切出(既定约束)。
### 2. 事件/信号路径(系统间通信,无紧耦合)
```
A2 ──cell_revealed / flag_judged / round_end(棋盘路径)──▶ B1(轮 facts 缓冲)
A3 ──round_end(stopped 直发,payload 同构)──────────────▶ B1
B1 ──notify_settlement_done(next_round_mode) / notify_combat_end──▶ A3
B1 ──apply_effect / apply_damage / grant / 伤害单据 submit…──▶ B3/B2/B4(唯一调用方;段内伤害序=主角先手→逐敌还手→地图账殿后〔案C 2026-10-06〕)
B1 ──install_board / retire_board──▶ A2 B1 ──generate(L,D)──▶ A1
D1 ◀──呈现数据源:A2 事件流 / B1 步骤流 / A3 ap-rap / ConfigDB display_name
```
- **事件载体(已定)**:组合根直连信号接线 + B1 Waiting 相位触发(不依赖事件到达序);autoload 全局事件总线已否决(2026-09-12,沿革见 git 历史)——单线程回合制沿用组合根直连(KISS)。
- 事件规范序:A2 发射序 = 触发格 BFS、8 邻行主序;事件序契约 `flag_judged` < `round_end` 全路径统一。
- **呈现层订阅禁令(切片缺陷②教训固化)**:呈现层永不直接订阅 排雷玩法/行动经济 的事件流,只订 战斗结算 步骤流与 `level_runner`——核心事件形态变化不得直接冲击界面。
### 3. 存档/读档路径(MVP 无存档;契约已锁)
- MVP 无元进度持久化(C4/D3 归 Alpha)。**已锁契约**:续玩/复盘快照 = master_seed + 各流 scope 计数器 + 意图序列 + 窗口选择序列;快照切出须发生在无正在执行中的 `open_stream` 实例时(scope 事件边界外——B1 编排保证:切点 = board install 边界)。
- 可回放性已实证:切片冒烟同种子双跑步骤流逐行相同(B1 AC-33 前身)。
- D3 Alpha 期按此契约设计格式;SCHEMA_VERSION 高版本拒读。
### 4. 打包与字体(CJK 随包发行)
CJK 字体随包发行并设为 theme 默认字体——运行时默认字体无中文字形。此项是 HUD框架 正式化的硬性前置,同时进导出 checklist 核对项。
### 4. 初始化顺序
```
进程启动
→ autoload 实例化:ConfigDB → RngService → SaveManager → MetaProgression(顺序固定;战斗编排器等核心类为普通类、由组合根按局实例化)
→ ConfigDB._ready():load_tables 加载 + 校验(致命通道;失败 = 构建中止 + 错误清单)
→ 主场景(D1 组合根)装配视图单元 + 信号接线
→ C2 begin_run:RngService.set_master_seed()(唯一接线方;两流计数器全零前提)
→ B1.begin_battle(encounter):set_reload_gate(true) → B3 开域 → B2 spawn → A2 install_board(A1.generate) + B4 roll_board(恰一次)→ A3 notify_round_start
→ 挖掘循环 …… → battle_over 清理序列 → set_reload_gate(false)
→ 关卡末:通关结算(钥石/GP/专长 level_clear 渠道——现行语义归 冒险结构 GDD;原 clear_inventory 随库存轴下线退役 2026-09-15)
```
**启动后置条件**(2026-10-17 用户裁入册——迭代 28 以冒烟 V2a–V2f 共 11 条断言把「启动完成后玩家该看到什么」成文;执行判据事实源在 `game/tests/system_test.gd`):
1. ConfigDB 就绪且表已载(`is_ready` + hero 表在座)。
2. 系统设置已落引擎态——Master 音量 mute/volume_db = settings_store 现值;减动效开关 = `UiKit.motion_scale`。
3. 启动态菜单可见(boot 后自树顶向下第一个可见内容层 = 开始层——菜单被冒险屏盖住即红)。
4. 续玩钮可见态恒等于断点在档态(双向:无断点隐藏/有断点可见/清断点回隐;boot 路径与刷新单口同源)。
5. 闲时会话已在树(`run_scope` 非空、非冒险会话、在树——永非 null 契约的启动侧证明)。
6. 调试浮窗 boot 不自动开(菜单优先,2026-10-16 用户令)+ 调试入口全局浮层角标 boot 可见。
---
## API 边界
> 完整 API 面(含封闭枚举负空间、布尔受理口径、输入×相位矩阵)以各 GDD AC 前言为**规范源**——本节列边界契约与不变式,实现须与 GDD 逐字一致;冲突时以 GDD 为准并走接口漂移修订。
| 边界 | 契约要点 | 调用方必须遵守的不变式 | 模块保证 |
|---|---|---|---|
| D1 → A2 | 意图经 `settle_batch(intents)` 提交;不直调 A3 | 单意图帧收集;stop 经批次委托 | 语义序仲裁 + voided 零副作用 |
| A2 → A3 | 挖/插/拔 = 先棋盘面判定后 `try_spend`;A2 不可自行扣减 | 相位判定两侧一致(同一矩阵) | 原子事务(余量+扣减+仲裁一体) |
| A2 → 下游 | 只外发三事件,payload 字段封闭(digit 恒真透传 / reward_eligible / variant_ids) | 增删事件 = 接口漂移 | 发射面封闭 + 规范序 |
| B1 → B2/B3/B4 | 全调用面集中 B1;调用序钉死(按摇定技能行兑现→apply_damage→commit_action;先兑付后衰减;段内伤害序=主角先手→逐敌还手→地图账殿后〔案C 2026-10-06〕) | 禁第二调用方(静态扫描域:API 符号命中文件 ⊆ B1 文件集) | 恰一次编排纪律(roll_board/decay/清理全序) |
| B1 ↔ A3 | 编排期代理 `request_refresh`(玩家意图,禁 RAP 满自动刷);回发 next_round_mode/battle_over | stopped/ap_exhausted 未刷新回发 new_board = 违约 fail-fast | 刷新受理契约(同 Waiting 多次合法) |
| 各系统 → D2 | ConfigDB 类型化属性单点读取 | 禁绕过 ConfigDB load 表、禁缓存副本、禁玩法数值字面量、禁 randomize()/自建 RNG | 校验双通道 + fail-fast 致命 |
| A1 → A2 | Board 产物 class_name 数据契约 | install 四不变式校验(violation = 拒绝 + 五类诊断枚举) | 生成期合法性闸(R₀≠S / clearable / min_safe) |
| A1 ↔ B1 | attempt 边界非 scope 事件;actuals p10 为对账输入(非 target 参数) | 编排不把重试当取号 | 生成期指标集输出(实测可推理率 / 实际雷数与安全格数 / 重试次数 / 降级与非法产物标记) |
| B4 → B3 | buff 类经 B1 调 apply_effect(B4 零跨系统读、零直接接口) | 满层拒绝 = 零兑付 + 明细行(无折算) | 授予时数值快照(抗热重载) |
| B1 → D1 | [步骤流行协议](../../gdd/systems/战斗循环/战斗结算.md#明细流水每一行都能指回你刚才的哪一步棋)(15 类封闭枚举 + 公共字段 type/source_class/origin_cell/round_index/display_name/value/highlight? + 特有字段 target/effect_id/pool_value) | 无来源行 = 断言失败;呈现侧禁按行序重演 B2 状态机 | 可回放步骤流(同种子逐行相同) |
**引擎类型核验注记**:接口使用的引擎类型 = Resource / .tres(D2 全表)、RefCounted(容器类)、Signal/Callable(事件载体)、Control/CanvasLayer/Drawing(D1)、SceneTree headless 协议(测试)——均属 4.x 基线稳定面;4.7 Control 域增量(offset_transform_* 等)已在 breaking-changes.md 登记,D1 采纳前对照核实。
---
## 架构原则
1. **核心层纯逻辑、headless 完整可跑**——核心层/功能层玩法逻辑零 Control/场景引用、零 UI 依赖;`--headless --script` 可跑完整战斗(D2 Rule 7 工程债;切片 88 冒烟实证)。输入是意图对象、输出是事件流/步骤流,D1 与输入设备皆可替换。
2. **单一事实源与零字面量**——玩法数值只存在于 `data/tables/*.tres`,经 ConfigDB 类型化单点读取;代码零玩法数值字面量;参数禁止跨系统复制(D2 Rule 1/2)。
3. **封闭 RNG 与可回放**——玩法代码零随机;一切随机经 RngService 具名封闭流(增流走 P1 评审);同种子 + 同输入序列 ⇒ 事件流/步骤流逐位相同(结算禁 await,B1 承重约束)。
4. **编排唯一性与事件面封闭**——战斗域跨系统调用权集中 B1(静态扫描承载);A2 三事件面封闭即负空间;每格受理、每雷转化、每次推进、每次衰减各恰一次。
5. **fail-fast + 零特判**——数据错误一律致命中止(错误数值上线比崩溃更伤);API 非法 = 拒绝 + 诊断不静默;变异零运行时分支(行为差异全部由生成端约束保证)。
6. **依赖单向 + 组合根模式**——层间单向依赖、唯一回边 = A2 事件订阅面;核心写调用唯一发生在组合根;禁上帝对象(切片 1100 行 main.gd 反面案例 → 9 单元拆分)。
7. **呈现层契约成文**——面向呈现的信号载荷必须有成文 schema;模态覆盖层必须有"打开时遮挡物隐藏"场景级断言;场景级 UI 探针测试为标配(切片缺陷 ①②④⑤ 教训沉淀)。
8. **系统无状态**——效果引擎这类系统零运行时可变状态:数据由宿主对象持有并随宿主生灭,状态按参数传入系统,系统只做判定(立项判据=2026-10-19 用户会话裁定;落地=迭代 32 卡②,2026-10-21 用户裁写入)。系统实例不持计数器——计数器住桶(round/battle/level/adventure 四桶,EffectContext 引用束),桶住宿主。
---
## 未决问题
| ID | Summary | Priority | Resolution Path |
|----|---------|----------|-----------------|
| QQ-01 | 渲染器选择(Forward+ vs gl_compatibility)与项目窗口基线 | High | **已落定**(2026-09-12):gl_compatibility + 1280×800 基座(canvas_items + expand);沿革见 git 历史 |
| QQ-02 | 事件总线载体与 A2 事件捕获测试 API | High | **已落定**(2026-09-12):组合根直连 signal + Waiting 相位触发;autoload 全局总线否决 |
| QQ-03 | gdUnit4 是否引入并迁移冒烟用例 | Medium | **已落定**:deferred(现行双载体承载;D2 OQ1 关闭) |
| QQ-04 | 轮内刷新数值连锁(清图支配性条款⑤ / 真人刷图行为获取期望)重算 | Medium | playtest 实测 |
| QQ-05 | 战斗末可选类"j==0 补发 1 件"兜底是否采纳(切片遗留待办) | Medium | playtest + B4 GDD 修订批 |
| QQ-06 | 可选类退出格子池后 buff 频率被动上升(44%→59%)的难度对冲杠杆(敌 HP / 权重 / 幅度) | High | C3 调参 + 切片数据复测 |
| QQ-07 | 标错惩罚(A2 OQ1:候选敌方伏击+1;hit=false 无去重的不对称裁决) | Medium | 原型小补丁实测会话(可与 v3 终验合并) |
| QQ-08 | B5 双舞台陷阱(战斗发生在棋盘上还是独立场景) | Low(B5 前) | 战斗表现美术测试后裁决 |
| QQ-09 | C3 消费 B1 对账输出的事实依赖回写 `design/gdd/02-系统清单.md` | Low | C3 GDD 定稿时 |
| QQ-10 | `.claude/docs/director-gates.md` 缺失(TD-ARCHITECTURE/LP-FEASIBILITY 判据无载体) | Low | 补建 gate 定义文件或维持 solo/lean 模式约定 |
| QQ-11 | A1 生成性能姿态(F2c 常数 C 定稿;切片实证 10×10/12×12 同步生成可接受,WorkerThread 留扩展) | Medium | A1 GDD 修订批 |
| QQ-12 | 零伤害死局跨字段/跨表护栏落点(B2 OQ9;推荐 D2 跨表校验——切片 LevelTable 校验⑧先例) | Medium | D2 校验设计批 |
| QQ-13 | A1 EC5 运行期熔断(连续降级确定性回退已知好种子) | Low | A1 GDD 修订批 |
| QQ-14 | A5 探测显影接口 / D3 存档格式(RNG 快照契约已在案,格式归 Alpha) | Low | 秘宝域正式化 / D3 Alpha 设计批 |