docs(qa目录退役): design/qa/ 清空删除,四路分流+§11 立接收方条款

- 40 张取证照与同名对比报告 → game/tests/evidence/ui-audit-2026-10-06/(该目录既有章程「人工测试证据」,目录根新增 .gdignore 令 Godot 整目录跳过导入,图不生成 .import 边车也不进导出包;parity/anchor.json 走文件系统路径读取不受影响)
- 有接收方的两份审计(代码术语审计→06:546+迭代31 卡①/测试审计→测试分层卡片)平移 design/research/;iter27-探针迁移对照(T1 未施工=活交付物)迁 reports/,reports/README 放什么表补一行交付物类型
- 已核销的迭代18-实机目检总清单(2026-10-14 十八项全过)删除,顺带清掉其内 4 条指向 8e02dcf0 已删件的回指
- doc-conventions §11:暂存地唯一归 design/research/,验证凭据不归文档目录;新增「落档必写接收方」一行——写不出接收方的不落文件,内容在会话里交付
- tools/balance_verifier.py 报告与原始数据改落 sim-data/(QA_DIR→READINGS_DIR)
- 活指针 13 处改判:AGENTS.md:22/30 与 Project Layout game 行、06:546、07:103、career 卡片×4、art-bible §8.2 L490 与 生涯.md:81 两处 8e02dcf0 遗留死指涉、game/tests/README 分级表与台账行、reports/README
- 结构闸白名单三处同批收口:IMAGE_PREFIXES 去 design/qa/ 加 game/tests/evidence/、DESIGN_SUBDIRS 去 qa、RETIRED 加 design/qa(目录复活即 FAIL)
- .qoder 技能 doc-consistency-check 两处指路改判(harness 配置不入 git,主区直接改)

单件试跑全绿:gdd_lint 10/10、doc_link --strict 死链 0、doc_term --strict 疑似现行 0、pipeline_gate 63 条目/21 卡、repo_structure_audit PASS。
本批 diff 触及 game/ 路径,合回需全量档回执(含代码域测试),待用户点名。
This commit is contained in:
DKChan committed 2026-10-20 02:07:39 +08:00
1 parent becb675aca
commit 75fafc3965
61 files changed
+43 -75

No files matched your search

@@ -0,0 +1,122 @@
# 代码术语审计报告
日期:2026-10-18
触发:用户裁定——GP 是唯一正式命名(「金币」系 AI 噪音);「插旗」全库禁用(正式名=封印);「旗」概念不存在;「雷格」「惩罚格」已退役(正式名=危险格)
---
## 1. 裁定摘要
| 禁用词 | 正式替代 | 裁定依据 |
|--------|---------|---------|
| 金币 | GP | GP 是唯一正式命名,「金币」系 AI 产出噪音,不应存在于任何位置 |
| 插旗 | 封印 | 游戏中不存在「旗」概念,右键动作=封印 |
| 旗(作为游戏概念) | 封印印记 | 同上——「不存在任何旗相关的东西」 |
| 封印(作为比喻解释) | 封印(作为正式术语) | 封印是正式动作名,不是比喻;禁止以「比喻」框架描述 |
| 雷格 | 危险格 | 2026-10-11 已裁退役 |
| 惩罚格 | 危险格 | 2026-10-11 已裁退役 |
| flag_*(代码键名) | seal_* | 用户裁定全换 |
---
## 2. 命中统计
| 禁用词 | 命中次数 | 涉及文件数 |
|--------|---------|-----------|
| 金币 | 116 | 44 |
| 插旗 | 210 | 61 |
| 雷格 | 109 | 31 |
| 惩罚格 | 8 | 4 |
| flag_(.gd) | 270 | 29 |
| flag(.tres) | 22 | 4 |
| flag(独立词 .gd) | 22 | 10 |
| **合计** | **~757** | **~100+(有重叠)** |
注:「封印」现有 170 处命中(46 文件),其中大部分是正确用法(封印=正式术语),但部分语境把它当「比喻」或「对外表达」描述,需修正措辞。
**读数订正(2026-10-18 需求卡片 v1.4 实测,本表数字保留作历史读数不作施工依据)**:上表的 game/ 侧数字用现行代码复现不出。同一命令口径实测(`game/` 内、区分大小写逐处计数):含 `flag` 的 .gd 53 个文件 595 处 + .tres 4 个文件 22 处,剔除 `size_flags_*`(70 处/19 文件)与 `_fatal_flag`(4 处)后**净 543 处/42 个文件**;「金币」39 处、「插旗」62 处、「雷格」75 处、「惩罚格」1 处、「旗」含复合词 376 处。两处口径错误:①中文三词用的是**全库**读数(全库实测 金币 381/插旗 600/雷格 394 处),被记进了 game/ 范围行;②flag 侧低估约一倍(原记 270+22+22=314)。施工判据以 [需求卡片-代码术语刷新批](../research/需求卡片-代码术语刷新批-2026-10-18.md) §2 的复现命令为准。
---
## 3. 分域明细
### 3.1 玩家可见文本(P0 最高优先级)
UI 字符串、toast、tooltip、display_name、desc 字段中出现的禁用词:
| 文件 | 行 | 内容 | 问题 |
|------|-----|------|------|
| game/presentation/views/shop_overlay_view.gd | 51,101,109,174,191 | `"金币 0"` / `"金币 %d"` / `"现价 %d 金币"` / `"刷新 %d 金币"` | 金币→GP |
| game/presentation/camp_shop_presenter.gd | 180,190,202 | `"金币不足——买不起这件商品"` / `"金币不足——刷新失败"` | 金币→GP |
| game/presentation/curio_interact_controller.gd | 192 | `"金币不足——刷新失败"` | 金币→GP |
| game/presentation/battle_narrator.gd | 24,114 | `"商店房:金币 %d"` / `"金币袋%s\n金币 +%d"` | 金币→GP |
| game/presentation/views/curio_pick_overlay.gd | 122,124 | `"刷新 %d 金币"` / tooltip 含「金币」 | 金币→GP |
| game/presentation/views/legend_overlay.gd | 14 | `"金=金币"` | 金币→GP |
| game/presentation/hud_presenter.gd | 169 | `"不能插旗:此格已有旗"` | 插旗→封印,旗→封印印记 |
| game/presentation/main.gd | 967 | `"插旗后轮末自动判定标中"` | 插旗→封印 |
| game/presentation/views/legend_overlay.gd | 9,11 | `"右键插旗(1AP)"` / `"封印印记(呈现名·不能拔)"` | 插旗→封印 |
| game/data/tables/treasure_items.tres | 212 | `"插旗不限相邻"` | 插旗→封印 |
| game/data/tables/reward.tres | 188 | `"display_name": "金币袋"` | 金币袋→GP 袋(或用户定名) |
| game/data/tables/feats.tres | 多处 | desc 含「封印」 | 需逐条核验语境(非比喻即合法) |
| game/tests/unit/presentation/reward_overlay_test.gd | 31,49 | `"金币袋\n金币 +20"` / `"刷新 20 金币"` | 测试断言里的 UI 文本 |
### 3.2 代码注释与内部文档(P1)
约 500+ 处分布在 .gd 注释、game/README.md、design/registry/entities.yaml、design/gdd/ 各系统文档中。主要模式:
- `# 挖雷格/标错旗` → `# 挖危险格/标错封印`
- `# 插旗不可逆` → `# 封印不可逆`
- `# 雷格恒无变异` → `# 危险格恒无变异`
- `# 金币袋兑付` → `# GP 袋兑付`
- `flag_place` / `flag_hit` / `flag_cell` / `has_flag` / `tex_flag` → `seal_place` / `seal_hit` / `seal_cell` / `has_seal` / `tex_seal`
### 3.3 代码标识符(P1,影响面最大)
flag_* 族标识符 270 处(29 个 .gd 文件)+ 22 处(.tres),涉及:
- 核心逻辑:minesweeper_rules.gd(18)、battle_orchestrator.gd(17)、grant_segment.gd(23)、effect_engine.gd(9)
- 数据表:action_economy.tres(2)、feats.tres(15)、settlement.tres(3)、treasure_items.tres(2)
- Schema:settlement_table.gd(3)、treasure_item_table.gd(3)、action_economy_table.gd(4)
- 呈现层:board_view.gd(7)、battle_end_overlay.gd(9)、ui_input_probe.gd(23)
- 冒烟/测试:smoke_all.gd(105)、level_autoplay.gd(16)、各 test 文件
### 3.4 设计文档(P1)
design/gdd/ 和 design/registry/ 中约 200+ 处,需随术语表修正同步更新。
### 3.5 历史文档(P2)
design/research/(提案、需求卡片)、design/qa/(审查报告)、design/art/(美术文档)中的命中:
- 历史提案和已结案需求卡片:留档不改(记录当时语境)
- 美术文档中的「封印旗」「封印特效」:需逐条核验(封印合法,旗不合法)
- roadmap.md:历史条目留档
---
## 4. 术语表自身修正清单
术语表(design/gdd/术语表.md)需按新裁定修正的条目:
| 行 | 现行内容 | 问题 | 修正方向 |
|----|---------|------|---------|
| 14 | `旗 / 控制` 条目 | 「旗」概念不存在 | 改为「封印 / 控制」,删除「旗插在危险格上」措辞 |
| 28 | `GP(局内金币)` | 「金币」是噪音 | 改为 `GP`,删除「金币」别名 |
| 126 | `雷格 / 惩罚格 → 危险格` | 对照行,合法 | 保留 |
| 138 | `禁用字面:「雷」「插旗」…禁止进入对外命名` | 范围不够——插旗应全库禁用,不只是对外命名 | 扩大为全库禁用 |
| 139 | `插旗的对外表达 = 封印` | 封印不是「对外表达」,是唯一正式名 | 改为「封印=正式术语(全库统一)」 |
| 154 | v1.6 修订记录「插旗对外=封印…机制文档内部用语不受限」 | 内部用语也禁用 | 修正 |
---
## 5. 风险评估
- **flag_* → seal_* 重命名**是最高风险项:涉及核心游戏逻辑(排雷规则、战斗编排、结算授予段),改错会破坏游戏行为。必须全量冒烟通过。
- **.tres 数据文件**中的 flag 键名改动需与 schema 同步,否则数据加载失败。
- **smoke_all.gd 单文件 105 处 flag_**,是改动密度最高的文件。
- 中文文本替换风险较低,但量大面广,需防漏改和误改(如「旗」字在非游戏语境出现)。
---
## 6. 建议拆批
见同目录需求卡片:`design/research/需求卡片-代码术语刷新批-2026-10-18.md`
@@ -0,0 +1,352 @@
# 测试审计 — 单测覆盖与验收门禁标准(2026-10-15)
> 审计会话产物。**只审计不改实现**(讨论期只改文档铁律),本文件是结论载体,不是执行批。
> 加载能力:`godot-builder`(headless / CI 编排 / 探针闸)+ `godot-auditor`(never-list 执法、类型与信号衰减扫描)。
## 〇、审计口径(先声明,避免误读结论)
| 项 | 口径 |
|---|---|
| 是否跑测 | **未跑**。本会话属审计类,不在 AGENTS.md「测试执行两入口」(迭代 loop / 用户点名)之内,全程零游戏调用 |
| 结论来源 | 静态阅读 + 仓库内既有登记数据(README / 架构文档 / AGENTS.md / active.md)+ 两个 deterministic 扫描器实跑(类型闸、信号衰减闸,只读) |
| 未验证项 | 「当前是否全绿」不在本次范围;本报告不主张任何红绿状态 |
| 覆盖判定 | 以「测试/冒烟源码中**直接指名**该类或该文件名」为据。**不排除经调用链的间接覆盖**——故「零指名」应读作「无直接断言面」,不等于「逻辑完全未被执行」 |
| **证据等级** | 见 §九。**A 类结论=代码/配置直读,确凿;B 类=仓库文档登记可查;C 类=静态推断,需实测坐实**。下表凡标 ⚠ 者为 C 类 |
| **CI 实态** | **已移除(2026-10-15 用户令)**。`git remote -v` 无输出=无远端;`.github/workflows/` 预接线件从未执行过一次,用户裁「CI 没有用、后面也不打算用、不留死配置」⇒ **全数删除**。本报告凡提「CI」处,均为**删除前的历史状态描述**;现行门禁一律读「**本地闸**」 |
---
## 一、结论速览
| 诉求 | 现状 | 判定 |
|---|---|---|
| ① 最单元的逻辑代码有单元测试 | `game/tests/unit/` 27 套件全登记入 `run_all.gd` manifest(零孤儿测试文件),412 处断言;core 层 28 个模块中 **4 个零直接指名** | **基本成立,有明确缺口** |
| ② 整体模块有接口测试 | `tests/integration/` 空壳已删;契约面仅 `system_contracts_test.gd` 15 断言单点 | **不成立 —— 集成层零承载** |
| ③ 系统级 UI 与场景切换测试 | UI 有 4 探针入 CI(结构/对比度/布局/输入),但**判定靠 PASS 串**;场景(屏壳)切换在 CI 上**零断言** | **半成立 —— 有面无判、切换无覆盖** |
| ④ 门禁不是「只冒烟」 | CI 三处判定缺陷(不查退出码 / 无 SCRIPT ERROR 闸 / 无断言数下限) | **不成立 —— 现状语义就是「没崩即过」** |
**一句话**:仓库里其实已经有很强的一套东西(`smoke_all.gd` 6128 行 / 967 处断言点 / 全系统覆盖,且**在本地轻闸里每次变更都跑**),但它叫「冒烟」;CI 里跑的那套叫「逻辑冒烟」的其实是单元测试——**而 CI 从未通电**(无远端)。术语与强度倒挂,加上门禁全靠人记得跑,共同构成了「冒烟观念」的制度性源头。
---
## 二、L1 — 单元层盘点
### 2.1 资产面
| 指标 | 实测 |
|---|---|
| 单测文件 | 27 个(`game/tests/unit/` 五族:battle_settlement / contracts / core / data_config / presentation) |
| manifest 登记 | `run_all.gd:_suites()` **27 条,与磁盘文件一一对应**(含 `example_test`;无孤儿、无漏登) |
| 断言点 | 412 处(`Kit.check` / `Kit.check_quiet` / 各套件本地 `_check()` 合计) |
| 断言出口 | 24 套件走 `test_kit.gd`,**4 套件自建**(`tree_requires_level` / `tree_rules_v11` / `config_db_fatal_oob` / `pacing_queue`) |
| 致命类用例 | 3 条 `expect=1`(config_db_fatal_oob / treasure_target_violation / reward_dangling_treasure),独立进程判退出码 |
### 2.2 断言质量抽查(正向证据)
抽查的三个套件是真值断言、且**带反例**,不是「存在即通过」:
- `tree_requires_level_test.gd`:schema 四拒(悬空键 / 阈值 <1 / 类型错 / 合法零违例)+ 判定三态(未达拒购 / 无阈值不受影响 / 达标开放)+ 投影两态(`gate_text` 拼装与清空),逐项比对期望字符串。
- `tree_rules_v11_test.gd`:四键合成行与 `rebuild` 实装面**逐字段行数对拍**(实现删分支/漂移即红),聚散两键断零行,并显式留了「反例护栏失效」断言——即**测试自身也在被测**(防假绿)。这是本项目里质量最高的一件。
- `damage_math_test` / `damage_controller_test`:纯函数 + 伤害单据五配方,34 断言。
⇒ 单元层**不存在**「普遍只判非空」的问题。已扫 `!= null` / `== null` 类断言 36 处,散布于各套件,未构成主体。
### 2.3 覆盖缺口(core 层直接指名 = 0)
| 模块 | 生产码引用 | 单测/冒烟直接指名 | 备注 |
|---|---|---|---|
| `minesweeper_rules`(MinesweeperRules) | 5 处 | **0** | 挖矿核心规则(揭示/扩散判定),无直接断言面 |
| `status_container`(StatusContainer) | 5 处 | **0** | 状态(buff/debuff)生命周期容器 |
| `config_db_resolver`(ConfigDbResolver) | 4 处 | **0** | 表解析 |
| `config_db_cross_validator`(ConfigDbCrossValidator) | 3 处 | **0** | 跨表护栏本体(config_db_test 只间接经 `db.load_tables` 触发) |
另有 `skill_lottery`(4 处引用 / 4 处指名 ✓)、`board_data`(42 / 4 ✓)、`reward_economy`(smoke 24 命中 ✓)已补位。
### 2.4 呈现层(presentation)缺口
`game/presentation/` 共 49 个 `.gd`(含 views 28 / scenes 3)。**有单测直接指名的约 11 个**:main、modal_flow、modal_stack、run_scope、treasure_interact_controller、board_view、camp_overlay_view、curio_pick_overlay、node_overlay、ui_kit、row_pacer(经 `pacing_queue_test` 承载,命名不对应)。
零单测指名的 **38 个**,其中高频/高风险的包括:`hud_presenter`、`battle_narrator`、`ui_assembler`、`stage_world`、`board_world`、`board_zone_view`、`board_cell_unit`、`standee_body`、`status_panel`、`status_slot_row`、`toast_stack`、`settings_store`、`camp_shop_presenter`、`curio_interact_controller`、`debug_session`、`adventure_screen` / `camp_screen` / `menu_screen`(三屏壳)等。
承载情况:其中 `board_view`(7) / `ui_kit`(4) / `status_panel`(5) / `standee_body`(2) / 三屏壳(1-2) 被 `game/smoke/*` 探针指名——**有覆盖,但覆盖的是结构 / 对比度 / 布局几何,不是行为**。
---
## 三、L2 — 接口 / 集成层盘点
**结论:零承载。**
- `game/tests/README.md` 自述:`integration/` 目录空壳已于迭代 19 卡① T4 删除,仅留章程句。章程登记的四类待建用例 —— Core-Core 集成、回放确定性(同种子步骤流逐行相同)、存档/RNG 快照往返、A1×A2 双包含端到端 —— **全部未落地**。
- 契约面唯一实体:`tests/unit/contracts/system_contracts_test.gd`(15 断言)。它是**单元级契约断言**,不是跨系统集成执行。
- 有一件**已建但不入任何闸**的重器:`tools/parity_anchor.py` + `game/tests/evidence/parity/anchor.json` —— 迭代 27 建的确定性对拍锚,三变体(base / attune / shop)× 20 局 × RUNSUM+JSONL 双面,字节级逐位一致。功能上它**正好是章程里「回放确定性」那一类集成用例**,但它是 `tools/` 下的手工工具,README 未登记、CI 零调用、闸表未收录。
⇒ 这是三层里**缺口最大的一层**,且已有现成零件未被收编。
---
## 四、L3 — 系统层(UI 行为 + 场景/屏切换)盘点
### 4.1 「场景切换」在本项目的真实形态
全库 `change_scene` / `change_scene_to_file` / `change_scene_to_packed` **零命中** —— 项目不用引擎级场景切换,改为 `main.gd` 三屏壳(`menu_screen` / `camp_screen` / `adventure_screen`)+ `visible` 互斥编排(迭代 27 T1 场景拆分)。
⇒ 因此「场景切换测试」在本项目应落实为:**屏壳显隐互斥 + 流程编排(菜单→冒险→营地→战斗→结算→回营地)的状态断言**。
### 4.2 现状
| 面 | 载体 | 是否入 CI |
|---|---|---|
| 屏壳拆分结构 | `smoke_all.gd:_smoke_scene_split()`(:147) | **否**(smoke_all 不进 CI) |
| 屏切换行为走查 | `ui_click_probe.gd`(含 `_exit_level_screen()`、结算终局、放弃二击) | **否**(归 `probe_gate --click`) |
| UI 结构(互压/等宽/出屏/零尺寸) | `ui_struct_probe` | 是 |
| UI 文字对比度 ≥4.5:1 | `ui_contrast_probe` | 是 |
| 视口/四区几何恒定(1280/1920 两档) | `ui_layout_probe` | 是 |
| 真实 `push_input` 输入路径十七断言 | `ui_input_probe` | 是 |
| 视觉 golden 逐像素 | `render_gate.sh` + `golden_compare.py` | **否**(窗口化,禁入 headless) |
⇒ **CI 上的场景/屏切换断言 = 0**。四个入 CI 的探针全是**静态结构与几何**,没有一件断言「点了这个钮以后屏切了、状态对了」。
---
## 五、门禁标准审计(本次重点)
### 5.0 前置事实:无远端、无 CI,门禁 = 本地闸(A 类,实测;2026-10-15 后续处置已执行)
`git remote -v` 无输出——**仓库无远端**。`.github/workflows/tests.yml` L4 自陈:「仓库已初始化 git(尚无远端)——本 workflow 在首次 push 到 GitHub 后自动生效」。⇒ 这份配置**从未在 GitHub Actions 上执行过一次**,是 2026-10-08「CI 预接线批」留下的预接线件。
**用户 2026-10-15 裁决**:「CI 是没有用的,后面也不打算去用它」⇒ **`.github/workflows/` 全数删除,不留死配置**(已由 `ci-removal-20261015` 分支执行)。同时用户立规:**不建、不留、不参考任何 CI 配置;改门禁只改本地闸**(已入 AGENTS.md 硬性红线)。
⇒ **验收门禁自始至终就是本地闸**,由 AGENTS.md 纪律驱动人工执行:
| 本地闸件 | 是否每天在跑 | 判定是否有洞 |
|---|---|---|
| `tools/run_smoke.py`(冒烟三闸) | 批末四闸之一 | **无洞**(退出码+摘要失败数+脚本错误扫描) |
| `game/tests/run_all.gd`(27 套件) | 批末四闸之一 | **有洞**(无脚本错误扫描、无断言下限) |
| `tools/probe_gate.sh`(探针段) | 批末/轻闸 | **有洞**(四件不查退出码) |
| `tools/render_gate.sh`(golden) | 周期重闸 | 容差带宽,时效存疑(§5.5) |
| `game/tests/static_scan.sh` | 双跑(本地+CI) | 八条域只落地四条(§5.6) |
**这对前文的修正**:§5.2 列的三处判定缺陷**不是"CI 的缺陷",是本地闸的缺陷**——它们此刻就在生效,每天在跑。CI workflow 只是把同一套有洞的判定**抄了一份到 Linux 形态**(L59-75 的 `run_probe` 明写「镜像 probe_gate 判定逻辑的 Linux 形态」)。
⇒ 因此**修判定必须修本地闸**;只改 CI 等于给一台没插电的机器换零件(而该机器现已拆除)。
同时暴露一个更尖锐的事实:**没有 CI,意味着"跑不跑闸"这件事没有任何机制约束,全靠人记得。** 本地闸判定再严密,不跑就等于没有。
### 5.1 术语倒挂 —— 「冒烟观念」的制度性源头
| 名 | 实际是什么 | 规模 | 在哪跑 |
|---|---|---|---|
| 「冒烟」(`smoke_all.gd`) | **系统级逻辑 + 接口 + UI 全栈断言面** | 6128 行 / 967 处 check 调用 / 运行期 **1086 项**(active.md 494 条最新登记,2026-10-15 closeup 批) | 仅本地 `tools/run_smoke.py`;**CI 零调用** |
| 「逻辑冒烟」(`run_all.gd`) | **单元测试套件** | 27 套件 / 412 处断言 | CI |
| ~~「Headless smoke」(CI job 名)~~ | ~~静态扫描以外的全部 CI 验证~~ | — | **已随 CI 删除(2026-10-15)** |
最强的一层叫「冒烟」,进了 CI 的那层也叫「冒烟」。当所有东西都叫冒烟,团队的验收心智就自然停在「跑一遍不崩」——**这不是人的问题,是命名的问题**。
> **v1.2 修正(重要,别被上一段带偏)**:「最强的一层不被执行」这个说法**不准确**。`AGENTS.md:116` 的**轻闸定义首项就是 `run_smoke` 全量**(即 `smoke_all` 1086 项)+ `ui_input_probe`,且「可随变更执行」。也就是说它**确实在跑**,只是靠人记得跑、不在自动门禁里。
> 准确的结论是:**`smoke_all` 有执行、无自动门禁;`run_all` 有执行、进了 CI(而 CI 未通电)。两者都不缺执行,缺的是「判定可靠」与「机制约束」。**
「冒烟」一词同时指代逻辑单元测试与系统级断言面(2026-09-12 测试载体决策的遗留词汇),**没有单元 / 集成 / 系统三层概念**;其验收判据只有一句「冒烟 + 探针全绿为提交门」。AGENTS.md:106 的「批末四闸」也沿用同一词汇表。
### 5.2 CI 判定语义的三处缺陷
**① 探针不查退出码**
`tools/probe_gate.sh` 与 `.github/workflows/tests.yml` 对 `ui_input` / `ui_struct` / `ui_contrast` / `ui_layout` 四件的判定是:
```
超时(124/137) → FAIL ; 否则 日志含 "PASS" 串 → 绿
```
**退出码完全不参与判定**(全库仅 `ui_click_probe` 查了退出码)。探针若在打印 PASS 之后才崩溃/遇脚本错误,CI 判绿。这是「只跑不判」的标准形态——与测试载体决策自己在 §Migration/§Risks 里警惕的路径一致。
**② 无 SCRIPT ERROR 闸门(最关键)**
`tools/run_smoke.py` 有三闸:退出码 + 摘要失败数 + **扫描输出中的 `SCRIPT ERROR` / `Parse Error`**。本地生效。
CI 直接调 `godot --headless --script res://tests/run_all.gd`,**③闸缺失**。
而项目自己记录过这条灾害(AGENTS.md:21、`run_smoke.py` 头注):*GDScript 运行时脚本错误不改变进程退出码、不计入失败数,且会静默中断所在函数的剩余断言 —— 首跑「309 项 0 失败」实为断言未跑全*。真实复发两次有档可查:
- active.md 476 条:迭代 21 基线冒烟 864/0,但 `run_smoke` 判 FAIL(SCRIPT ERROR 51 行,`_flush_pending_reveals` 空 source_class 触发)。
- active.md 494 条坑册②:`--script` 模式编译器不解析裸 autoload 标识符 → **`pacing_queue_test` 实证 Parse Error**。
⇒ 第二次那条尤其要紧:它证明 **Parse Error 就发生在 CI 会跑到的套件里**。有 `run_smoke` ③闸时它被当场抓住;没有③闸的 CI 上,它只会表现为"断言少跑了一截、退出码仍是 0"。
⇒ **这条灾害路径在 CI 上完全敞开**,且 CI 的 `run_all.gd` 是逐套件子进程模型,任一套件脚本错误中断 → 该套件 `failures` 仍为 0 → `Kit.finish` 返回 0 → CI 绿。⚠(C 类:判定链为代码直读,但「CI 上实际会假绿」需造反例实测坐实,见 §九 T0-①)
**③ 无断言数下限闸**
`test_kit.gd:finish()` 在 `failures == 0` 时打印 `all green (%d checks)` 并 `quit(0)`。`checks == 0` 同样算绿。套件因异常早退、或 manifest 被误删条目,CI 都不红。
### 5.2b 附带缺陷:CI 注释漂移(新发现,A 类)
`.github/workflows/tests.yml` L7 头注写的是「四探针=ui_input/ui_struct/ui_contrast/ui_layout」,但 L52 / L55 的执行段注释仍写「轻闸**三**探针」,实际 L72–L75 跑的是**四个**。注释与代码不符,是「注释即文档」纪律的破口——后续维护者照注释改闸极易漏件。
### 5.2c 附带缺陷:示例测试在 CI 占位跑(A 类)
`run_all.gd:29` 把 `example_test.gd`(26 行 / 2 断言,样板件)登记进生产门禁。它每次实跑并计入「27 套件」,既虚增计数又占一个子进程。
### 5.3 自动门禁 弱于 本地重闸
> **v1.3 订正**:本节原有的「本地重闸 vs CI」对比表**已作废**——CI 侧于 2026-10-15 全数删除,不再存在第二套门禁。作废表保留于下仅供历史沿革,勿据此决策。
| | 本地重闸(AGENTS.md:116,唯一门禁) | 已删除的 CI 配置(历史) |
|---|---|---|
| 静态扫描 | S1–S4 + S9 + S10 | 同(static-scan job,从未执行) |
| 单元 | run_all 全套 | 同 |
| 系统逻辑 | **run_smoke 全量(1086 项,轻闸首项)** | 无 |
| 探针 | 轻闸 + `--click` + `--full`(八件) | 仅 4 件 |
| 渲染 golden | render_gate | 无 |
| doc 三闸 / 熵增闸 | 有 | 无 |
| 确定性对拍 | parity_anchor(手工) | 无 |
| SCRIPT ERROR 闸 | 有(run_smoke ③) | 无 |
⇒ **唯一的门禁就是本地闸,且它全靠人记得跑。** 这既是好消息(不存在"两套里弱的那一套"问题,改一处即可),也是坏消息(没有任何机制强制"跑"这个动作)。
### 5.4 测试资产台账缺口:`game/smoke/` 17 个无宿主脚本(新发现,A 类)
`game/smoke/` 下 38 个 `.gd` 中,只有 11 个配了同名 `.tscn`(即探针形态);其余 **17 个是无 `.tscn` 宿主的纯脚本**:
```
adventure_monte_carlo auto_player battle_driver board_stat_probe
calibrate_boards damage_probe defense_scan dump_battle
experiment_density level_autoplay monte_carlo probe_ui_util
reward_expectation rhythm_batch skill_rhythm_probe smoke_all
verifier_batch
```
其中 `smoke_all` 是已知的系统断言面(T0 级,1086 项),`probe_ui_util` 是探针公共库,两者定位清楚。**其余 15 个(MC 模拟、防御扫描、节奏批、标定批、验证批、掉落期望、autoplay 等)性质介于「测量工具」与「测试」之间**:无宿主、无闸、README 未登记、CI 零调用。它们既不入 `run_all` manifest,也不入任何闸表,属于**测试资产台账上的游离件**——无人能回答「它们是否仍在役、是否还能跑、结果由谁判」。
### 5.5 golden 视觉基线时效存疑(新发现,B 类)
`tools/golden_compare.py:11` 载明基准冻结于 **2026-09-30**(v3.5 视觉落码 + 营地终稿 + 分辨率案甲后)。此后迭代 25(全局主题资源挂载、两处局部主题做法退役)与迭代 26(按钮五态、全局纹理过滤 Nearest、三处换墨、光柱 alpha)两次大改呈现层。
active.md 只记「render_gate golden 0.00%(登记即结未重制)」——即**基线未随呈现层换代重制仍判 0.00%**。两种可能:① 换代面确实未落在 golden 裁剪区(则基线仍有效);② 基线已失效而容差带(灰度差 >16 占比 ≤2%)宽到吃下了变化(则闸形同虚设)。⚠ 需实测判别(见 §九 T0-⑤)。
### 5.6 静态扫描域:登记八条只落地四条(A 类)
`game/tests/static_scan.sh` 实跑:S1/S2(全局随机+RNG 自建)、S3(warning 级)、S4(core 禁 UI 依赖)、S9(类型闸)、S10(文件头闸)。
**S5 / S6 / S7 / S8 四条仍在 TODO 段、从未实现**(脚本末 `# TODO(正式工程落地后精化为扫描配置并升格为硬失败)`)。其中 S5(core 禁裸引用 autoload 全局标识符)恰恰是 active.md 494 条坑册②实证踩过的坑(`--script` 模式 Parse Error)——**有真实反面案例,按 code-conventions「新违规案例必须先补扫描规则再修码」纪律,本就该补规则**。
⇒ 扫描域半数未落地,且未落地的那半里有已踩过坑的一条。
---
## 六、缺口清单(分级)
### A 级 — 门禁语义(不改代码,只改判定;收益最高)
1. **本地闸补 SCRIPT ERROR 闸门** —— 复用 `run_smoke.py` ③闸逻辑,对 `run_all` 的每个子套件输出扫 `SCRIPT ERROR` / `Parse Error`。
2. **`probe_gate.sh` 探针判定改为「退出码优先 + PASS 串兜底」** —— 四件探针全部对齐 `ui_click_probe` 段的口径。
3. **断言数下限闸** —— `Kit.finish` 在 `checks == 0` 时判红;`run_all` 汇总校验套件数等于 manifest 条目数。
4. ~~**CI 纳入 run_smoke(系统逻辑面)**~~ —— **v1.3 作废**:CI 已删除;且 `run_smoke` 本就是本地轻闸首项(1086 项随变更跑),此条从不成立。
5. ~~**CI 卫生两件**(订正 L52/L55「三探针」注释)~~ —— **v1.3 随 CI 删除而消失**。保留其中一件:`example_test.gd` 退出生产 manifest(或转正为真实套件)。
### B 级 — L2 集成层(缺口最大)
5. 重建 `tests/integration/`,优先收编现成零件:`parity_anchor.py` 纳入闸表(它本就是章程里的「回放确定性」用例)。
6. 补「存档 ⇄ RNG 快照往返」「Core-Core 编排」两类章程已登记的集成用例。
### C 级 — L3 场景/屏切换
7. **屏壳切换断言件**:三屏壳 `visible` 互斥 + 菜单→冒险→营地→战斗→结算→回营地 主流程状态机断言,做成可入 headless CI 的探针(当前 `ui_click_probe` 是唯一近似物,但不入 CI)。
### D 级 — 覆盖补洞
8. 补 `minesweeper_rules` / `status_container` / `config_db_resolver` / `config_db_cross_validator` 四个 core 零指名模块的直接单测。
9. 呈现层 38 个零单测件按风险排序补面(建议先 `hud_presenter` / `battle_narrator` / 三屏壳)。
### E 级 — 测试代码自身卫生(Aurelius 视角)
10. **S9 类型闸显式豁免 smoke/tests**(`tools/audit_type_hints.py:5` 注释「smoke/tests 豁免——测量面容器直构是惯例」)⇒ 测量面实测 untyped `Array`/`Dictionary`:**`game/tests/` 24 处 + `game/smoke/` 133 处 = 157 处**无闸管(产品码侧则归零)。这是项目既有裁决,此处仅呈报事实,不构成改判建议。
11. **`test_kit.gd` 用 `static var` 全局计数器** —— 注释已声明「单进程跑多套件须先 `reset()`」。当前靠「一套件 = 一子进程」回避,是**约定不是机制**;将来改并发执行即串台。
12. **断言出口不统一** —— 4 套件自建出口,`Kit` 24 套件;汇总口径不可比。
13. **`load("res://core/xxx.gd")` 字符串路径**(`tree_rules_v11:15-16`、`tree_requires_level:11-12` 等)—— 重命名即静默返回 null → SCRIPT ERROR → 在**无③闸的 CI 上可能假绿**(与 A-1 联动)。
14. **`.connect(func(...))` lambda 订阅共 76 处**(`game/tests/` 10 + `game/smoke/` 62 + 生产码 4)—— lambda 不自动断连,信号源存活久于目标即泄漏。测试侧集中在 `breakpoint_resume_test` / `settle_segments_test` / `forge_workbench_test` / `reward_overlay_test` / `ui_input_probe`。
### F 级 — 台账与时效(v1.1 新增)
15. **`game/smoke/` 15 个游离测量脚本**定性(工具 vs 测试):在役的入台账 + 入闸或明示不入闸;失效的退役。**S10 文件头闸已能管住格式,但管不住"这东西还算不算数"**。
16. **golden 视觉基线时效判定**(冻结 2026-09-30,经历 iter25/26 两次呈现层换代)——判有效则留,判失效则显式重制并呈报。
17. **补 S5 扫描规则**(core 禁裸引用 autoload 全局标识符)——按 code-conventions 纪律,已有真实反面案例(active.md 494 坑册②)却无规则;S6/S7/S8 是否同批补另行裁决。
---
## 七、建议的门禁分层标准(待裁,未落任何文件)
### 7.1 术语订正(建议)
| 现名 | 建议改为 | 理由 |
|---|---|---|
| 「冒烟」(`smoke_all.gd` / `run_smoke.py`) | **系统级断言面(system suite)** | 它是全栈逻辑+接口+UI 断言,不是冒烟 |
| 「逻辑冒烟」(`run_all.gd`) | **单元套件(unit suite)** | 它就是单元测试 |
| ~~CI job `Headless smoke`~~ | ~~`Unit + System + Probe`~~ | **v1.3 作废**——CI 已删除,无 job 可改 |
> 冒烟(smoke)一词建议**只保留给**「能否启动、能否加载表、能否进主屏」这类秒级存活检查,**不再作为验收主词**。
### 7.2 三层语义与判定口径(建议)
| 层 | 验什么 | 判定(三条并行,缺一即红) |
|---|---|---|
| **L1 单元** | 纯逻辑 / 公式 / schema 校验 / 状态机 | ①退出码 ②断言有真值比对,禁「非空即过」 ③**断言数 > 0** |
| **L2 接口** | 模块间契约 / 跨系统编排 / 确定性回放 / 存档往返 | ①退出码 ②**逐位一致对拍**(已有 parity_anchor 现成) ③脚本错误扫描 |
| **L3 系统** | UI 行为 / 屏壳切换流程 / 视觉回归 | ①退出码 ②**行为断言(点击→状态变更)**,非仅几何结构 ③golden 逐像素(周期闸) |
**通用三条硬闸(对所有层)**:
1. 退出码 —— 唯一权威判据,**PASS 串只作日志,不作判据**;
2. 脚本错误扫描 —— `SCRIPT ERROR` / `Parse Error` 命中即红(消灭「假绿 0 失败」);
3. 断言数下限 —— 零断言即红(消灭「静默早退」)。
外加既有的:外部 wall-clock 超时(124/137 = 挂死判红)。
---
## 八、未决项(待用户裁决,本报告不代决)
| # | 事项 | 说明 |
|---|---|---|
| Q1 | 是否按 §7.1 订正术语 | 涉及 AGENTS.md、README 的措辞 |
| ~~Q2~~ | ~~`smoke_all.gd` 是否并入 CI~~ | **v1.3 作废**——CI 已删除;且 `run_smoke` 本就在本地轻闸首项 |
| Q3 | `tests/integration/` 是否重建 | 重建则 L2 有了承载;也可选择只把 `parity_anchor` 收进闸表而不建目录 |
| Q4 | S9 类型闸是否收回对 tests/smoke 的豁免 | 现行豁免是项目既有裁决(E-10),仅呈报 |
| Q5 | 屏壳切换探针是新建还是改造 `ui_click_probe` 入**本地轻闸** | 新建面更纯;改造零成本但 `ui_click_probe` 实测耗时较长 |
---
## 九、报告自评 —— 这份审计本身哪里还不够(用户问,据实答)
### 9.1 十条自评(按严重程度)
| # | 不足 | 后果 | 补法 |
|---|---|---|---|
| 1 | **全静态、零实测** | 最硬的结论(探针不查退出码 → 会假绿)是**推断**,不是证据。审计拿推断当结论,本身就不严谨 | 造反例实测:让一件探针/套件必然失败,看 CI 判定是否真绿(T0-①) |
| 2 | **覆盖靠 grep 指名** | 「零指名」不等于「零覆盖」,我已在 §〇 打了预防针,但**没有替代度量手段** | Godot 无内建行覆盖率;退而求其次 = 用脚本加载/调用登记反查,或引进第三方覆盖率工具(待裁) |
| 3 | **没给执行矩阵** | §七 只给三层语义,没给「谁在什么时机跑」——门禁不落到时机等于没落 | 补:每次提交 / 每次 PR / 周期 / 里程碑 的四级时机表 |
| 4 | **没测时长预算** | 原定 <30s,`run_all` 已是 27 个子进程、CI 给 120s;套件再增就撞墙 | 实测 run_all 全套 + smoke_all 时长,重定超时值(T0-②③) |
| 5 | **漏审 `game/smoke/` 游离件** | v1.0 完全没提 17 个无宿主脚本 —— 测试资产台账缺一大块 | 已补 §5.4 / F-15 |
| 6 | **漏问 golden 基线时效** | 基线冻结于 iter25/26 两次 UI 大改之前,却仍判 0.00%,没追问 | 已补 §5.5 / F-16 |
| 7 | **漏审扫描域未落地** | 只在 E-10 提了 S9 豁免,没把「扫描域八条只落地四条」当独立缺口 | 已补 §5.6 / F-17 |
| 8 | **漏抓 CI 注释漂移与 example_test 占位** | v1.0 没扫 workflow 注释与 manifest 内容质量 | 已补 §5.2b / §5.2c / A-5 |
| 9 | **A–E 分级无排序依据** | 分档是我主观排的,没绑投入产出比 | A 级之所以排第一:**改判定不改代码、半小时收益最大**;F 级排最后:属台账清理,不影响正确性 |
| 10 | **没区分证据等级** | 读者无从判断哪条可信、哪条要验 | 本版起 A/B/C 三级标注(§〇)+ ⚠ 记号 |
| 11 | **没核实 CI 到底通不通电**(v1.2 补,最严重的一条) | 我把 CI 当主战场审了一整章,`git remote -v` 一查——**无远端、从未跑过**。整章的结论"方向"没错(判定逻辑确实有洞),但"落点"错了:洞在**本地闸**里,此刻就在生效;CI 只是一份没插电的镜像。差点把改造矛头指向一台从没开过的机器 | 已补 §5.0;改造对象改为本地闸为主、CI 同步对齐为辅 |
### 9.2 证据等级表
| 等级 | 定义 | 本报告中的典型 |
|---|---|---|
| **A(确凿)** | 代码/配置直读可复现 | 探针判定不查退出码(`probe_gate.sh` / `tests.yml:59-75`)、`Kit.finish` 零断言仍绿(`test_kit.gd:41-49`)、CI 无 SCRIPT ERROR 闸、S5–S8 未实现、CI 注释三 vs 四、17 个游离脚本 |
| **B(文档可查)** | 仓库登记在册 | 灾害「309 项 0 失败」、active.md 476 条 51 行 SCRIPT ERROR、494 条坑册② Parse Error、golden 冻结日、integration 空壳已删 |
| **C(推断,⚠)** | 逻辑推演,未实测 | 「CI 上实际会假绿」、「run_all 时长将撞 120s」、「golden 基线已失效」 |
### 9.3 一句话
这份审计**找方向是准的**(术语倒挂、三处判定缺陷、L2 零承载,三条都是代码级确凿),但**证据硬度不够**——它是"读出来的结论",不是"跑出来的结论"。扭转方案的第一步必须是**先把 C 类结论全部坐实成 A 类**,否则后面所有改动都建立在我自己的推断上。
---
## 版本历史
- v1.0(2026-10-15):审计会话首版。范围 = 单测覆盖 + 验收门禁标准;未跑测,结论全出静态审计;缺口按 A–E 五级分档,§七为标准建议(待裁),§八列未决项。
- v1.1(2026-10-15 同日,应「报告有什么可优化」问询):①§〇 加证据等级列,全文 ⚠ 标注 C 类结论;②补 §5.2b CI 注释漂移、§5.2c example_test 占位、§5.4 游离测量脚本台账、§5.5 golden 基线时效、§5.6 扫描域半数未落地;③§六 增 A-5 与 F 级(15/16/17);④新增 §九 自评十条 + 证据等级表。仍未跑测。
- v1.2(2026-10-15 同日,应「CI 现在有用吗」问询):①§〇 加「CI 实态」行;②新增 §5.0(无远端、CI 从未执行、本地闸五件洞况表);③§一/§5.1 修正「smoke_all 不被执行」的错误表述(它本就在本地轻闸首项);④§九 自评补第 11 条(最大视角错误=未核实 CI 通不通电)。
- v1.3(2026-10-15 同日,**用户裁「CI 没有用、后面也不用、不留死配置」后**):①`.github/workflows/` 全数删除(分支 `ci-removal-20261015`),全文 CI 表述改注为「已删除的历史状态」;②§5.3「本地重闸 vs CI」对比表作废、改为「本地闸是唯一门禁」;③§六 A-4/A-5 中 CI 项作废(保留 example_test 一件);④§七/§八 中 CI job 改名、Q2 作废;⑤架构事实源纪律:历史决策文档只作沿革引用、不回改;现行事实以 architecture.md 为准。
- v1.4(2026-10-15 同日,用户裁「决策记录归 git commit log、不另存决策文档」后):七份历史决策文件已删(沿革归 git 历史),全文引用清除——原引用处改指 `design/dev/architecture/architecture.md`「测试与质量域」节;§5.6/Q1/时长预算等表述随清;结论本体零改动。
@@ -16,7 +16,7 @@
3. `game/data/tables/adventure.tres:8-22` 旧三档配额结构(curio_quota_attack_common 18 等);`:31-34` 凭证四参(chance 20/quota 2/limit 1/pity 5);`adventure_table.gd:22` 注释仍写旧资源四项。
4. `game/core/adventure_runner.gd:44` Boss 通关兑付=**提升三选一**(信号注释「非末关通关恰一次」)+部分回血——与目标设计(专长三选一+回血)不符,属换代非新增;`:411-440` `_apply_curio_pick`:kind="relic"→`_feats` 持有集、refresh→`_attune_refresh_x`、属性类走 CURIO_APPLY_ROUTES 声明式路由(新加算类零代码);`:93-95/:819-826` 凭证保底/限购/出现三计数器在役;`:218-219` 断点扩列先例(feat_ticket_pity/sold)。
5. `game/data/tables/treasure_items.tres:76,111` 淬毒刃纹/封印爆裂(原标中殉爆)两行在役待迁(迁出即删)。
6. 冒烟基线 840 项 0 失败(design/qa/iter19-card0 出口报告);MC 链=adventure_monte_carlo.gd+analyze_playtest.py 聚合。
6. 冒烟基线 840 项 0 失败(iter19 出口报告已随中间文档退役,读数原样记于此);MC 链=adventure_monte_carlo.gd+analyze_playtest.py 聚合。
7. 06 在册:秘宝实装批条目(③专长侧联动由本卡承载)、生命比例扩签前置条、旧 MC 行为锚作废重锚归数值批条。
8. 秘宝充能账在役(attunement.gd)——凭证件「同调电池」的跨层写入目标账已存在,不依赖秘宝实装批。〔**2026-10-18 注**:同调电池经用户裁**删除**,本条前提对后续批不再成立;`attune_charges` 账本本身作为秘宝基础设施保留〕
@@ -120,7 +120,7 @@
| req-card 技能(`~/.workbuddy/skills/req-card/SKILL.md`,仓外用户级) | §7 验证闸:补「每条验收测试须配变异验证项」要求 | **机械面,随批**(T6;仓外文件,随批改不入 git) |
| [07-体验验证清单](../gdd/07-体验验证清单.md) | 新增目检节:F5 启动态(主菜单在顶层、按钮可点) | **机械面,随批**登记(不阻塞) |
| [active.md](../../active.md) | 收口快照+状态记录 | **机械面,随批**(收口时) |
| design/qa/iter28-实现报告-2026-10-15.md | 收口产物:各卡状态+代拍板追认单+GDD 反哺点节+变异验证记录表+冒烟断言数增量 | **机械面,随批**(收口时产出) |
| reports/iter28-实现报告-2026-10-15.md | 收口产物:各卡状态+代拍板追认单+GDD 反哺点节+变异验证记录表+冒烟断言数增量 | **机械面,随批**(收口时产出) |
| design/dev/architecture/architecture.md | 装配合同常量成为层序唯一事实源、boot 链路后置条件成文、run_scope 生命周期矩阵——若与现行陈述有差(iter27 反哺点在册:06 登记「场景分层/会话生命周期陈述滞后于实态」) | **反哺点**(列实现报告待用户裁决,另批落文;设计权威文档不随批更新) |
| [08-Alpha版本标准](../gdd/08-Alpha版本标准.md) | 测试基建四行(冒烟套件/单元测试套件/界面探针/机器可读的呈现断言,:128-132)状态不因本批改变——本批只加断言不加新设施类 | **无关联文档**(四行在役不变) |
@@ -205,7 +205,7 @@ L2 熊地精池(attack/lunge/heavy)对比 L1 熊地精池(attack/charge/he
1. `skills.tres` 两新行的 `skill_id` / `display_name` 命名形态(小写下划线 / 中文双字,与既有 12 行同风)——取值已定,形态细节自理。
2. `enemy_table.gd` / `unit_container.gd` 的写法沿用 `armor_type` 同款(可省略 + 缺省回退 + 未知枚举报错)。
3. MC 配对读数的种子沿用既有基线种子,报告落 `sim-data/` 或 `design/qa/` 随既有命名惯例。
3. MC 配对读数的种子沿用既有基线种子,报告落 `sim-data/` 随既有命名惯例。
4. N1 落值后若发现 (1,2) 需连带微调 `atk_min/atk_max`(现行 0-2)——**仅限本行**,且须登记。
5. `expect_pools` 6 键的键值同步写法(保持既有字典风)。
@@ -7,7 +7,7 @@
- **v1.4(2026-10-15 用户令「决策记录归 git commit log、不另存决策文档」)**:①历史决策文档体系整体废除,在效事实已由 10-15 文档批迁入 `design/dev/architecture/architecture.md`;②🔴 契约 5 改写为「架构事实唯一源」口径;③Q1 闭环、§5 同步面改写为 architecture.md;④全文引用清除。
- **v1.5(2026-10-16 roadmap 编入笔)**:roadmap 迭代 29 行改写为本批+新增「迭代 30+ 位空」行;§5 `roadmap.md` 同步行与排期行更新;订正 v1.3 条目尾部重复段。
- **v2.0(2026-10-16 三轮复查后定稿笔;用户令「实现相关的都可以用你推荐的,但重新检查一遍」)**:①**事实面改指针(N1 甲)**——§2 不再自持门禁/扫描域事实表,一律指 `design/dev/architecture/architecture.md`「测试与质量域」节(:135-178)三张表(五模块归属表/「三条判定硬闸现行状态」×5 闸矩阵/S1–S8 承接表),本卡只留**本批专属增量事实**;②**首轮 11 问按推荐案全裁**(Q1 闭环·Q2 作废·Q3–Q7 依推荐);③**第二轮 N1/N2 亦按甲**:N1=§2 改指针,N2=T6 收 S3 路径修正(+0.25d);④**订正四处事实**:PASS 串判定面实为 **8 件探针**(轻闸 4+`--full` 4,仅 `ui_click_probe` 查退出码)非 4;`game/smoke/` 实为 **29 个 `.gd`**(17 个无 `.tscn` 宿主)非 38;T5 的 `status_container` **不是零覆盖**(2 个单测已指名)→ 换 **`board_generator`**;README「门禁节已由 ci-removal 批改写」前提不成立(分支未合入)→ CI 残留 8 处改由本批 T2 清除;⑤**订正死引用**:`AGENTS.md:21/:106/:116` 与 §0 的 `:102-103`(该计数指当时 `CLAUDE.md` 压到 71 行;2026-10-19 改名后文件为 75 行,节号仍不存在)、`.github/workflows/tests.yml`(F3/F5/F6 直引已删文件)、`golden_compare.py:11`(实际 :13);⑥**新增架构文档回写义务**:本批落地后须把「三条判定硬闸现行状态」矩阵的「缺失」改「在位」、S 表 S3/S5 随之更新(§5)。
- 来源:[测试审计 — 单测覆盖与验收门禁标准 v1.1](../qa/测试审计-单测与验收门禁标准-2026-10-15.md)(`design/qa/`,2026-10-15;加载 `godot-builder` + `godot-auditor` 双技能审计产出)
- 来源:[测试审计 — 单测覆盖与验收门禁标准 v1.1](测试审计-单测与验收门禁标准-2026-10-15.md)(同目录 `design/research/`,2026-10-15;加载 `godot-builder` + `godot-auditor` 双技能审计产出)
- 归属:**测试基建批**(req-card §3:缺陷修复/工程债/**测试基建**/重构类工程需求凭 bug 证据或 06 在册条目直接写卡,**无设计定稿前置要求**——本批凭据即审计报告 A 类证据)
- 排期:**迭代 29**(2026-10-15 用户令;**2026-10-16 已写入 roadmap 迭代 29 行**——原「M4 顺延 29+」行随 M4 数值批废除改写为「迭代 30+ 位空」记录)。开工门=U0,须用户 `/iter` 发令。
- **并行性前提已满足**:iter28「启动装配与生命周期验收补全批」已于 2026-10-15 入库收口(冒烟 1086→1125/0),串行裁决的阻塞条件不复存在。开工即建 worktree 分支,主区只读铁律不变。