Merge branch 'agentsmd-20261019'

This commit is contained in:
DKChan committed 2026-10-19 06:11:42 +08:00
commit d7d3f28332
23 files changed
+689 -46

No files matched your search

View File
File renamed without changes.
+1 -1
View File
@@ -196,7 +196,7 @@
| 域 | 闸 | 本批改动落在这些路径即属该域 |
|---|---|---|
| **代码域** | run_smoke、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/`、根规则文件(`CLAUDE.md`/`roadmap.md`)、`tools/` 工具脚本、`.zcode/` 配置、`sim-data/`、`reports/` |
| **文档域** | gdd_lint、doc_link_audit、doc_term_audit、流水线闸 | 一切非 `game/` 的路径:`design/`、根规则文件(`AGENTS.md`/`roadmap.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 都不比。
+2 -2
View File
@@ -1,6 +1,6 @@
# 代码规范(Dungeon Sweeper)
> 约束范围:`game/` 代码同尺度;与 CLAUDE.md「硬性红线」节硬约束(数值表单点 / RNG 封闭流 / Core 零 UI / fail-fast / spec-AC 一致性)并行生效,冲突以用户裁决为准。
> 约束范围:`game/` 代码同尺度;与 AGENTS.md「硬性红线」节硬约束(数值表单点 / RNG 封闭流 / Core 零 UI / fail-fast / spec-AC 一致性)并行生效,冲突以用户裁决为准。
> 分工:本文管结构 / 契约 / 语言 / 数值 / 流程五类;测试的编写与验收见 `design/dev/test-conventions.md`;真实反例库见同目录 `code-conventions-cases.md`(不常驻加载,对规则适用有疑义时查)。
**写任何代码前必须通读本文件。**
@@ -34,7 +34,7 @@
机器闸:`tools/audit_file_headers.py`(static_scan S10:行数上限+黑名单机械可判子集)。存量头注按白名单清偿(约 90 文件,清偿批进行中);清偿落地后闸增补「头注必须 `##` 开头」锁死载体;此间新增/改动的文件头必须即合规。
### 1.5 禁止事实约定
任何"大家默认这么做"的惯例必须成文进本文件(或 CLAUDE.md)才算存在。写代码时发现未成文但必须遵守的约定 → 当场补条文,不许靠惯性延续。
任何"大家默认这么做"的惯例必须成文进本文件(或 AGENTS.md)才算存在。写代码时发现未成文但必须遵守的约定 → 当场补条文,不许靠惯性延续。
---
+2 -2
View File
@@ -1,6 +1,6 @@
# 文档写作规范(写文档前必读)
> **地位**:本文是文档写作的规范权威,与 `design/dev/code-conventions.md`(代码规范)对等;CLAUDE.md 只留导航指针,细则以本文为准。
> **地位**:本文是文档写作的规范权威,与 `design/dev/code-conventions.md`(代码规范)对等;AGENTS.md 只留导航指针,细则以本文为准。
> **适用范围**:`design/` 下一切现行文档与根目录 `roadmap.md`;概念建模与跨文档引用见 `design/dev/concept-conventions.md`。
## 0. 总纲
@@ -11,7 +11,7 @@
**读者测试是每个小节的验收标准**:只读这一节,回答三个问题——这节管的是谁/什么?在什么情况下?会发生什么?答不出来,就重写这一节,而不是给看不懂的地方补注释。
旧体系 lean 格式六条硬规则已停用,仅用于解读 `design/archive/` 旧文档(其表格占比口径为 30%)。`tools/gdd_lint.py` 现为现行文档机检三闸之一(gdd_lint / doc_link_audit / doc_term_audit,分级周期口径见 CLAUDE.md);可读性仍是第一内容质量门,lint 是格式机检面,两者并行。旧模板留档 `.claude/docs/templates/`。
旧体系 lean 格式六条硬规则已停用,仅用于解读 `design/archive/` 旧文档(其表格占比口径为 30%)。`tools/gdd_lint.py` 现为现行文档机检三闸之一(gdd_lint / doc_link_audit / doc_term_audit,分级周期口径见 AGENTS.md);可读性仍是第一内容质量门,lint 是格式机检面,两者并行。旧模板留档 `.claude/docs/templates/`。
## 2. 白话写作规则
+3 -3
View File
@@ -1,7 +1,7 @@
# 流程规范(Dungeon Sweeper)
> 约束范围:一切批次的流程纪律——分支与 worktree、五段流水线、批次工作流、测试执行细则、像素件工作纪律。
> 分工:硬性红线的一句话索引在 CLAUDE.md「硬性红线」;本文承载其操作细则;批次开工前通读本文。
> 分工:硬性红线的一句话索引在 AGENTS.md「硬性红线」;本文承载其操作细则;批次开工前通读本文。
**开工任何批次前必须通读本文。**
@@ -52,10 +52,10 @@
**完成**
10. **批末按域验收才合并**——在任务 worktree 内跑 `tools/run_all_gates.sh`,**按本批改动域选档**:本批改动触及 `game/`(游戏工程代码、测试、探针、场景)→ `--code`;不触及 `game/` 的一切改动(`design/`、根规则文件、`tools/` 工具脚本、`.zcode/` 配置等)→ `--docs`;同批混触 `game/` 与文档面 → 全量档不带参数。所选域全绿才合回 master。该脚本是全部验证闸的**唯一入口、唯一清单与唯一域划分**,闸件增减、分域调整都只改它;**本文与其他文档禁另列闸件清单**(清单散落多处正是 iter27 漏跑 `probe_gate --full` 的成因)。跑完写回执 `game/tests/.gates/receipt.json`(含 `domain` 字段),合回时由 worktree-guard 按 diff 路径推域强制校验。闸件(`tools/` 下机检脚本与闸壳)自身的改动不占合回全量——其质量义务=落批时的变异验证(test-conventions §6),闸真崩溃时合回闸 fail-closed(跑不出回执即拦),不以合回全量为兜底
11. **合并后主区按域复跑**——合并可能引入冲突或环境差异,落回 master 后按本批改动域复跑:触及 `game/` 的批=全量复跑(维持);纯文档域批=复跑文档域档(秒级),不再全量
12. **批次完成后的登记义务**——合回 master 后按 doc-conventions §12.1 推进 06 条目状态(做完整条删除),涉及迭代编排的在 roadmap 迭代总表与顶部「当前位」节换代,跨会话教训写记忆库。批次过程与结论由 git 提交信息承载,禁止再写会话状态文件(2026-10-18 用户裁,见 doc-conventions 第 10 节)。`design/` 与根规则文件(`CLAUDE.md`/`roadmap.md`)实现批禁写,见 §13
12. **批次完成后的登记义务**——合回 master 后按 doc-conventions §12.1 推进 06 条目状态(做完整条删除),涉及迭代编排的在 roadmap 迭代总表与顶部「当前位」节换代,跨会话教训写记忆库。批次过程与结论由 git 提交信息承载,禁止再写会话状态文件(2026-10-18 用户裁,见 doc-conventions 第 10 节)。`design/` 与根规则文件(`AGENTS.md`/`roadmap.md`)实现批禁写,见 §13
13. **文档同步闸(2026-10-17 改口径:实现批禁写文档)**——实现批**禁写 `design/` 整个目录与根规则文件**,要往外交代的东西一律落 `reports/`:实现报告 `reports/iter<N>-实现报告-<日期>.md`(各卡状态+实机目检总清单+遗留读数义务)、代拍板追认单 `reports/iter<N>-代拍板-<日期>.md`、GDD 反哺点清单 `reports/iter<N>-反哺点-<日期>.md`(每条写清哪个文件哪一节、改成什么、依据是什么)。设计权威文档(GDD/art-bible)**任何批都不直改**:用户在会话中逐点裁决后,由非迭代批(工具/规则/文档批)写入 `design/`,并把反哺条目从 `reports/` 清掉(吸收即死)。机械面文档(roadmap 行/registry/README 工具注)同样归非迭代批在合并前更新。反哺点未落地期间相关 GDD 节视为待反哺,读前先查 `reports/` 与 06;需求卡片必列「关联文档同步面」按两层标注
14. **实机目检归用户,只登记不阻塞**——真人检测项登记进实现报告目检总清单与 07-体验验证清单即完成批内义务;禁把等目检当停工理由或完成前置
15. **中间产物吸收即死**——细则见 CLAUDE.md 硬性红线与 doc-conventions 第 11 节
15. **中间产物吸收即死**——细则见 AGENTS.md 硬性红线与 doc-conventions 第 11 节
## 4. 测试执行两入口铁规(细则)
+1 -1
View File
@@ -1,7 +1,7 @@
# 测试规范(Dungeon Sweeper)
> 约束范围:`game/smoke/`、`game/tests/` 与一切场景探针的编写与验收。
> 分工:测试**执行许可**(什么时候允许跑测试)归 CLAUDE.md「硬性红线·测试执行两入口铁规」;**跑什么闸、什么顺序**归 `tools/run_all_gates.sh`(脚本即清单,本文与 CLAUDE.md 均不另列);本文管测试怎么写、怎么算合格。
> 分工:测试**执行许可**(什么时候允许跑测试)归 AGENTS.md「硬性红线·测试执行两入口铁规」;**跑什么闸、什么顺序**归 `tools/run_all_gates.sh`(脚本即清单,本文与 AGENTS.md 均不另列);本文管测试怎么写、怎么算合格。
**写任何测试前必须通读本文。**
+1 -1
View File
@@ -483,7 +483,7 @@
**现状**:qa 收尾批核查 iter19 系列出口报告遗留移交项时发现**不在 06 在册**的七项(acceptance-package §三.2/card0 §5.3/followup §七.3/uibackfill §6.2-4/verify §6.1/3/7)。已结案的(tree_rules 受理闭环、X/Y 双源、S1 七项违例修复、提灯目检项、tests.yml 休眠等)已在各报告标注结案证据,不入本条。七项均为挂号备查/顺路件,无排期承诺:
1. **design/diagrams 越界**(熵增闸存量红,archify 架构图批 00712d5 旧债):脚本自文「新分类先过用户拍板再改两处白名单」。修案二选一——甲=用户拍板 `design/diagrams` 入 DESIGN_SUBDIRS 白名单(archify 总图批产物归位);乙=迁出 design/ 归位合法区。**归属**:熵增闸白名单(CLAUDE.md Project Layout+脚本白名单两处)
1. **design/diagrams 越界**(熵增闸存量红,archify 架构图批 00712d5 旧债):脚本自文「新分类先过用户拍板再改两处白名单」。修案二选一——甲=用户拍板 `design/diagrams` 入 DESIGN_SUBDIRS 白名单(archify 总图批产物归位);乙=迁出 design/ 归位合法区。**归属**:熵增闸白名单(AGENTS.md Project Layout+脚本白名单两处)
2. **开场行后缀认加算区**(iter19 卡⓪遗留):现口径=「局外加成存在才带」后缀(需求卡片字面执行);局内有加算区 flat 但无局外加成时,开场行数字含加成却不带注记——是否扩展认加算区归设计批裁定。**归属**:冒险结构/战斗开场参数面
3. **camp STONE 文字位外溢**(iter19 尾裁微批遗留):camp_overlay_view.gd:116/:403/:414 等既有 STONE 文字位对现役牌色实测 3.59-4.02:1 区间(非在册违例、机检不拦);全站收敛 STONE→STONE_DEEP 另立裁点。**归属**:呈现优化批(对比度残余位)
4. **迷雾对三关扩对**(iter19 卡②遗留):素材不入 git 致三关逐关 floor avg 实查受限,ui_contrast 迷雾测点现按在册单值 #453020;素材入库或授权读素材后,以 tools 脚本算三关逐关 avg→最亮者核合成(最坏情况判据契约 7 完整化)。**归属**:对比度探针面(前置=素材可读授权)
@@ -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/时长预算等表述随清;结论本体零改动。
+1 -1
View File
@@ -222,7 +222,7 @@ entities:
type: glossary
owner: design/gdd/systems/排雷循环/排雷玩法.md(各词条以首次定义 GDD 为 owner)
attributes:
purpose: CLAUDE.md 用语纪律(2026-09-09)的登记通道——项目内生术语的白话定义集中地,GDD 首次出现处须附同款定义
purpose: AGENTS.md 用语纪律(2026-09-09)的登记通道——项目内生术语的白话定义集中地,GDD 首次出现处须附同款定义
terms:
双包含回验: 棋盘生成 与 排雷玩法 互检两条包含关系——臂① 排雷玩法 实际初始展开域 ⊆ 棋盘生成 生成期排除域(开局不触雷不触变异);臂② 棋盘生成 求解器初始可见态 ⊆ 排雷玩法 实际初始展开域(棋盘生成 度量不吃亏)
恰等: 两集合逐格相等(不多开不少开)
@@ -0,0 +1,61 @@
# 会话任务书:营地场景图 · 美术设计段
> 用途:本文件是给**另一会话**用的开工提示词(自包含,不依赖原会话上下文)。直接把「提示词正文」一节整段复制进新会话即可。
> 立此书的原因:美术设计段由用户在独立会话主导推进(美术线=用户自立批,不占迭代位)。
---
## 提示词正文
你是 g-plan2(Dungeon Sweeper,Godot 4.x 像素风 roguelike)项目的美术设计助手。本次只做一件事:**「营地场景图」的美术设计段**(五段流水线里的第二段:文档设计/美术设计)。写代码、写需求卡片、产出终稿素材都不在本次范围内。设计定稿后回主会话重立卡④,再谈实现。
### 1. 事项背景
营地交互重做批共五张卡,本次是**卡④·营地场景图新建批**:把现役营地 UI(框框式 `CampOverlay`)换成**一张可点击的营地场景图**——画面里有篝火、锻造工坊、床铺等物件,点物件进对应操作界面。用户原话要的是「一张营地的图片,跟 UI 的交互是点击图片中的某一处地方,然后再进入界面。不是完全普通的那种 UI 设计,不是各种框框的」。
### 2. 开工前必读(按序,读完再动手)
1. `design/research/需求澄清-营地交互重做-2026-10-18.md` —— **唯一事实源**:①目标体验原话 ②参照与反参照 ③非目标 6 条 ④目标结构树+纵深稿(远景天空/中景围栏+大门/近景篝火居中/左锻炉铁砧/右床铺宝箱)⑤10 条交互裁决 ⑥验收口径 ⑦切批原则
2. `design/research/需求卡片-营地场景图新建批-2026-10-18.md`(v2.2)—— 卡④现状与已裁事项(Q4/Q5/Q6/Q8 均裁定甲)、五项前置销号清单 **P1–P5**、归属纪律段
3. `design/gdd/ux/camp.md`(v1.5)—— 营地现有功能面(四柜台、钥石、商店)
4. `design/art/art-bible.md`(v3.15)—— §4.2/§4.6.3 色板权威面、§6.2/§7.5 场景与物件条款
5. `design/gdd/06-待办清单.md` 末尾「营地交互重做·五张需求卡片」条目 —— 状态机与销号出口在哪改
6. `design/dev/doc-conventions.md` §12.1(条目格式与状态机)§12.3(美术目录与命名)§12.4(特批标记)
7. `AGENTS.md` —— 项目铁律(尤其:讨论期只改文档不改 `game/`;美术线=用户自立批,不占迭代位)
可用用户级技能:`doc-design`(文档设计)、`asset-ingest`(美术录入)。
### 3. 本次议程:五件前置逐件销号
| 编号 | 事项 | 谁定 |
|---|---|---|
| P1 | 美术渠道 A/B(两案定义与代价见卡④ §10 Q1,先读再裁;推荐 A) | 用户裁 |
| P4 | 参照物(类型/构图/纵深参考) | 用户找 |
| P2 | 像素规格:画布尺寸档、瓦片与物件规格(Q6 甲=过渡口径已裁,执行归用户线) | 用户定 |
| P3 | 点选反馈设计稿:悬停/按下/禁用/已解锁各态怎么表达 | 用户线产出(未受命不开工) |
| P5 | GDD/art-bible 落文(`camp.md` 与 `art-bible.md`) | 定稿后用户发令才动笔 |
### 4. 硬约束(违即作废)
- **色板**:48 色令牌制,新增色须过 `tools/palette_check.py` 双门;**HSV 300°–345° 禁入带**;语义色不得串用;文字与图标对比度 **WCAG ≥ 4.5:1**
- **明度档必须在渲染合成空间(伽马)排档**——按 CIE L\* 线性排会把明度序排反(迭代 30 实测教训)
- **参照**:要「一张营地图画+点图上物件」,**不要各种框框**(反参照已写明)
- **非目标**:不做贴图重构批、篝火不绑休息、档槽不显未完冒险、冒险中不开营地、美术定档不翻案
### 5. 纪律红线
- 讨论期**只改文档,不动 `game/`**;素材生成与文档修改不进迭代位(铁律 2)
- 图片**永不进 `design/`**:在途素材放 `artwork/<YYYY-MM-DD-主题>/`(整目录不入 git),样张放其 `samples/` 子目录,终稿才进 `game/assets/art/<用途>/`
- 命名:全小写英文+下划线;终稿三段式 `<对象>_<部位或状态>_<规格>.png`,且**终稿名=代码消费名**(先定 ui_kit/资源路径常量,素材名跟它走,防断链);样张 `sample_<屏名>_<版本>.png`
- **Agent 定位**:美术与设计由用户主导,Agent 只做检索、比对、记录、成稿整理;**不代跑设计、不擅自产出设计稿或素材**(铁律 2 与铁律 7)
### 6. 完成定义(本次会话的出口)
1. P1–P5 五件全部销号且有落点(裁决记进卡片修订记录,条款写进 GDD/art-bible)
2. 06 末尾条目状态行按 §12.1 累积制追加「美术设计已闭合(样张过审、art-bible v3.x)」段——**凭据必须真实**,「已闭合」不带凭据非法
3. 回主会话:卡④按定稿重新立卡(现 v2.2 是「前置登记待解」态,**不是可开工卡**),再谈编入哪个迭代
4. 验收方式照澄清文档⑥:迭代内截图对比,最终用户目检(目检不阻塞迭代)
### 7. 用户自己要带的输入
参照物(P4)、渠道 A/B 的裁决(P1)、每轮「过/不过」的目检结论。
@@ -1,7 +1,7 @@
# 需求卡片:UI 全局主题批(引擎原生控件接管皮肤)
- 版本:v1.2(2026-10-13 审核补充批——中文字体防御性条款+V5 基线数订正+CheckButton 词条名补注+两处目检观察点+08 未跟踪状态提示;**卡片成立**,零待裁点,开工门=U0)
- v1.2 记录:同日用户对卡片发起审核,发现六点,除两处「提请注意」外全部落文。①**新主题必须显式设 `default_font`**(必修,见 §6 T0 第 4 步+新增断言 V6)——挂上项目主题后 `project.godot` 既有的 `theme/custom_font` 是否仍然生效,无权威依据可证实(官方文档对应页缺失,未跑测试);一旦失效后果是**全游戏中文字形缺失**,直接违反 HUD框架可访问性基线「中文字体随包内置并设为默认」。指向同一字体文件=观感零变化,纯粹消除不确定性。②V5 基线数订正 864/0 → **938/0**(v1.1 自审声称该项已修正,但正文数字从未落实)。③CheckButton 图标词条名为 `on`/`off`,不是 CheckBox 的 `checked`/`unchecked`(Godot 4),两者不可共用一套名。④目检增补两个观察点(滑轨柄是否抢焦点、滚动条槽是否可见)。⑤§5 标注 08-Alpha版本标准 至今仍是 git 未跟踪文件。**另已跑结构审计闸=PASS**:新增 `game/assets/theme/` 与 `game/assets/art/ui/gen/*.png` 均命中图像白名单 `game/assets/`,**无需**修订 CLAUDE.md Project Layout。**审核方订正**:其上一轮「界面美化三层诊断」称设置屏音量滑轨「已填段与未填段同一个深棕色」,实查两段为 #B8A582 与 #7A5232(对比 2.84:1,低于图形元素 3:1 参考线),「偏难辨」成立而「同色」不成立;且默认值 100 时无未填段。卡片 §2 末的疑点披露与此处理维持有效。
- v1.2 记录:同日用户对卡片发起审核,发现六点,除两处「提请注意」外全部落文。①**新主题必须显式设 `default_font`**(必修,见 §6 T0 第 4 步+新增断言 V6)——挂上项目主题后 `project.godot` 既有的 `theme/custom_font` 是否仍然生效,无权威依据可证实(官方文档对应页缺失,未跑测试);一旦失效后果是**全游戏中文字形缺失**,直接违反 HUD框架可访问性基线「中文字体随包内置并设为默认」。指向同一字体文件=观感零变化,纯粹消除不确定性。②V5 基线数订正 864/0 → **938/0**(v1.1 自审声称该项已修正,但正文数字从未落实)。③CheckButton 图标词条名为 `on`/`off`,不是 CheckBox 的 `checked`/`unchecked`(Godot 4),两者不可共用一套名。④目检增补两个观察点(滑轨柄是否抢焦点、滚动条槽是否可见)。⑤§5 标注 08-Alpha版本标准 至今仍是 git 未跟踪文件。**另已跑结构审计闸=PASS**:新增 `game/assets/theme/` 与 `game/assets/art/ui/gen/*.png` 均命中图像白名单 `game/assets/`,**无需**修订 AGENTS.md Project Layout。**审核方订正**:其上一轮「界面美化三层诊断」称设置屏音量滑轨「已填段与未填段同一个深棕色」,实查两段为 #B8A582 与 #7A5232(对比 2.84:1,低于图形元素 3:1 参考线),「偏难辨」成立而「同色」不成立;且默认值 100 时无未填段。卡片 §2 末的疑点披露与此处理维持有效。
- v1.1 记录:grilling 三裁点=①focus 族词条全不定义(弃 LineEdit focus 豁免案)②PopupMenu 并入预盖③色值卡审即冻结;自审修正=V5 基线数过期、新增 PNG 导入流程补写、LineEdit 占位文字色词条补入、.tres 溯源改 README;换代重验=状态面板改名批(master 7d1e9cb)后全部 file:line 逐一复验存活,pause_overlay.gd → status_panel.gd 一处文件名换代
- 来源:[06-待办清单](../gdd/06-待办清单.md)「UI 全局主题资源缺失——引擎原生控件没有接管皮肤」(2026-10-13 登记,UI 美化三层诊断 · 第一层);[08-Alpha版本标准](../gdd/08-Alpha版本标准.md) 三·界面表同名行
- 归属:呈现层表现批(纯工程改动,零美术素材,不动美术圣经 §7 定稿规格)
@@ -4,7 +4,7 @@
- 来源:[06-待办清单](../gdd/06-待办清单.md)「第二 / 三关棋盘观感——亮度与对比度」小节(2026-10-13 用户裁定条)+ [playnote](playnote.md) 用户试玩原始记录:「UI优化,第二第三关的棋盘看着太累了;不知道是因为亮度还是对比度的原因,看着非常费劲,非常不舒服」
- 归属:**表现层美术修批**(06 在册条目直接写卡;两轴归属 = [HUD框架](../gdd/systems/表现与支撑/HUD框架.md)(UI 轴)+ [美术圣经](../art/art-bible.md)(素材轴),定性前两方共裁——沿用 06 条裁决)
- 排期:**已编入迭代 30(2026-10-16 用户令编入,roadmap 行已在案;批内状态刷新列反哺点)**。同迭代三卡串行序位第 3:[未开格类型徽章批卡](需求卡片-未开格类型徽章批-2026-10-16.md)→[战斗一屏样张批卡](需求卡片-战斗一屏样张批-2026-10-16.md)→本卡(徽章→样张→观感)。**并行例外**:本卡 T1/T1b 采样与定性读数允许与前两卡并行穿插——依据=采样是只读动作(出帧/读数/样张均不触碰 golden 三张、样张主板、§5 同步面文档等汇聚文件),落码修改(T2 起)仍按上述序位串行。开工门 = U0,须用户 `/iter` 发令;且 T1 出口定性人闸未过之前禁止动码——该闸 = [06 本条](../gdd/06-待办清单.md)既有裁决硬步骤(「开工前先过『素材轴 / UI 轴』定性人闸」,2026-10-13 用户裁定;[08 版本历史](../gdd/08-Alpha版本标准.md) v0.3 同款注),**不是待裁点**(v1.1 撤销原 Q1,见 §10)。
- **立场前提(用户原话,本卡设计的第一约束)**:此条立项原因就是用户实机觉得现在的画面累眼、且对「纯程序化重产现状」明确不满——「如果还是用原有方式弄出来的东西,有没有可能还是我不满意的?」。本卡对此的正面回应 = ①第一步定性用**可量化的读数归因**(明度直方图 / 相邻格对比 / 高频能量 / WCAG 对),禁止凭感觉猜轴;②两条修法各自的产出物写清**相对现状新增什么**(§6 T2 两案效果上限表);③**诚实的效果声明**:观感是主观项,机检只能证伪(读数红 = 必有问题)不能证真(读数绿 ≠ 用户满意),**阻塞性人闸全部前置**(T1 定性闸 + 契约 4 方向闸),入库后实机目检按 2026-10-12 用户令口径**登记不阻塞**——目检项登记进 `reports/iter30-实现报告-<完成日>.md` 实机目检总清单(「入册 07」列反哺点;[CLAUDE.md](../../CLAUDE.md) 红线「真人检测只登记不阻塞——禁以等目检为停工理由」口径不变),用户复判否决走 §7 V4 回补机制(行回待做 + 06 立残留条,落文按 v3 口径归文档批)。防「改一轮还是不满意」的机制 = **先出改前/改后并排对比读数样张给用户定性确认方向,方向过了人闸才落码**(🔴 契约 4)——方向若被否决,返工停在样张层,不烧落码与基线。
- **立场前提(用户原话,本卡设计的第一约束)**:此条立项原因就是用户实机觉得现在的画面累眼、且对「纯程序化重产现状」明确不满——「如果还是用原有方式弄出来的东西,有没有可能还是我不满意的?」。本卡对此的正面回应 = ①第一步定性用**可量化的读数归因**(明度直方图 / 相邻格对比 / 高频能量 / WCAG 对),禁止凭感觉猜轴;②两条修法各自的产出物写清**相对现状新增什么**(§6 T2 两案效果上限表);③**诚实的效果声明**:观感是主观项,机检只能证伪(读数红 = 必有问题)不能证真(读数绿 ≠ 用户满意),**阻塞性人闸全部前置**(T1 定性闸 + 契约 4 方向闸),入库后实机目检按 2026-10-12 用户令口径**登记不阻塞**——目检项登记进 `reports/iter30-实现报告-<完成日>.md` 实机目检总清单(「入册 07」列反哺点;[AGENTS.md](../../AGENTS.md) 红线「真人检测只登记不阻塞——禁以等目检为停工理由」口径不变),用户复判否决走 §7 V4 回补机制(行回待做 + 06 立残留条,落文按 v3 口径归文档批)。防「改一轮还是不满意」的机制 = **先出改前/改后并排对比读数样张给用户定性确认方向,方向过了人闸才落码**(🔴 契约 4)——方向若被否决,返工停在样张层,不烧落码与基线。
---
@@ -84,7 +84,7 @@
🔴 **契约 4 · 样张先行、方向人闸后落码**:T2 任一修法落码前,必先出**改前/改后并排对比样张 + 读数表**给用户定性;用户未确认方向 = 停在样张层,禁先行改素材改常量。此条是「防改一轮还是不满意」的机制本体。**v1.2 注**:素材轴甲/乙裁决呈报件(§6 T1 呈报硬步骤)与本闸是同批产物——用户呈报现场裁甲后,裁甲案时本闸即已过关、不重复呈报;裁乙案时乙方向样张另走本闸。
🔴 **契约 5 · 机检 ≠ 观感,前置人闸承担方向证真**:读数达标只构成必要条件,机检不能证明满意——「证真」面由**前置**人闸承担(T1 定性闸〔06 已裁〕+ 契约 4 方向样张闸)。入库后的实机目检轮按 2026-10-12 用户令口径执行(CLAUDE.md 红线「真人检测只登记不阻塞」):目检项登记进 `reports/iter30-实现报告-<完成日>.md` 实机目检总清单即完成义务、不卡入库(「入册 07」列反哺点);**禁把「机检全绿」写成「用户满意」的等价表述**——用户复判否决时按 V4 回补(08 行回待做 + 06 记残留、下批重开,落文按 v3 口径归文档批)。(v1.1 改写注:v1.0 本条「完成判定必须含用户实机目检轮、目检未过禁宣布在役」与 2026-10-12 用户令冲突,已对齐。)
🔴 **契约 5 · 机检 ≠ 观感,前置人闸承担方向证真**:读数达标只构成必要条件,机检不能证明满意——「证真」面由**前置**人闸承担(T1 定性闸〔06 已裁〕+ 契约 4 方向样张闸)。入库后的实机目检轮按 2026-10-12 用户令口径执行(AGENTS.md 红线「真人检测只登记不阻塞」):目检项登记进 `reports/iter30-实现报告-<完成日>.md` 实机目检总清单即完成义务、不卡入库(「入册 07」列反哺点);**禁把「机检全绿」写成「用户满意」的等价表述**——用户复判否决时按 V4 回补(08 行回待做 + 06 记残留、下批重开,落文按 v3 口径归文档批)。(v1.1 改写注:v1.0 本条「完成判定必须含用户实机目检轮、目检未过禁宣布在役」与 2026-10-12 用户令冲突,已对齐。)
🔴 **契约 6 · golden 基线换代显式化**:改图必破基线——重制走 `tools/golden_baseline_refresh.sh` 显式流程(缺省模式重制棋盘三张:board_shot_probe 抓帧→`golden_board_crop.py` 按 meta 坐标裁剪→覆盖 `game/tests/golden/` 三张;触及菜单态加跑 `--menu`),并逐屏呈报换代面(新旧基线并排,沿 render_gate S2 停机点口径);权限与义务=呈现批 agent 自行换代、**提交说明强制写明触发原因**(refresh 脚本头注 Q6 在册);前置=素材齐盘(脚本逐项守卫,缺位拒跑)。**禁先刷基线后改图**(基线是判据不是障碍物)。
@@ -286,6 +286,6 @@
| 7 | Q1/Q3 已裁检索 | **Q1 属已裁项**:06:449 条内明文「开工前须先定性(沿用既有裁决)」+ 状态行「开工前先过定性人闸」(2026-10-13 用户裁定)+ 08 版本历史 v0.3 同款注——v1.0 一边在 P1 引该裁决、一边把同一闸列为 Q1 待裁,自相矛盾,触用户红线。Q3(同批与否)与 Q2(甲/乙)全库检索**无既裁**(06 单条覆盖两关但未裁批次数;playnote 无;git log 无)——保留为待裁 | 06:445-453;08:220(v0.3);playnote.md:5;git log 2026-10 检索 | Q1 从 §10 删除、改 P1/T1 出口/V1 流程硬步骤引用(§10 载明移除理由);Q2/Q3 保留 |
| 8 | 中立性 | v1.0 四处「推荐」:Q1(已裁项附裁决,撤销后消失)、T1 出口句(撤销)、T3「推荐=同批」与 §10 Q3「推荐 甲」(**无既裁依据→中立化**)、Q2 立场句「开工默认先做甲案候选样张」(改写为白名单内样张层探针动作,非路线裁决) | 全文 grep 推荐=0 残留(仅剩「已删字样」自述与列名注) | 列头改「卡片立场(不代裁)」;§10/§6 T3 中立化 |
| 9 | 跨卡依赖 | 两卡同抢 L2/L3 板面:徽章批(类型微光实装者,其 T0-② 五组明度档以未开格底 L≥0.30 为基线——本卡改的正是该基线;art-bible :379 已册「格底与微光同在未开格面,邻近色相有吞没风险」互辨复测义务;其 §4「不动格底/瓦片/四槽」系单向避撞);样张批(Q1 丙案语义=样张反提素材规格、Q3 路线选型——本卡乙案重产与其冻结次序互锁) | `需求卡片-未开格类型徽章批:13/82/109`;`需求卡片-战斗一屏样张批:33/59/70-71/168/170`;art-bible:379 | 新增 **§4B 跨卡依赖**(X1/X2/X3 三行+结论笔:次序与规格联动问题,不新增裁点,随 Q2/Q3 呈报交用户定序);§8 L3 增⑥跨卡次序破裂停机型 |
| 10 | 外加翻案(非清单内,敌意自查所得) | **契约 5/完成定义 3/V4/T5「目检未过禁宣布完成/在役」与 2026-10-12 用户令红线冲突**:CLAUDE.md「真人检测只登记不阻塞——禁以等目检为停工理由」(入库先例:迭代 25/26/28 均入库翻行、07 目检留残,git 提交 d337c9e5 立规)。另:F1「L1 10×10」不全——`board_gen.tres` level_index 1 段含一行 **12×12 dungeon**;F10/C6:类型微光引擎未实装(徽章批 F2 引 HUD框架实装状态行佐证),v1.0 把它当实机可测层不成立 | CLAUDE.md:63;git log d337c9e5;roadmap 迭代 25/28 行「残留人闸=目检」先例;`game/data/tables/board_gen.tres` 行段实查 | 契约 5 重写(阻塞闸全前置:T1 定性闸+契约 4;V4 改登记不阻塞+回补机制:否决→08 行回待做+06 记残留重开);F1 补两板型注;F10/T1 微光测面降为样张 v2 证据级别并注升级路径 |
| 10 | 外加翻案(非清单内,敌意自查所得) | **契约 5/完成定义 3/V4/T5「目检未过禁宣布完成/在役」与 2026-10-12 用户令红线冲突**:AGENTS.md「真人检测只登记不阻塞——禁以等目检为停工理由」(入库先例:迭代 25/26/28 均入库翻行、07 目检留残,git 提交 d337c9e5 立规)。另:F1「L1 10×10」不全——`board_gen.tres` level_index 1 段含一行 **12×12 dungeon**;F10/C6:类型微光引擎未实装(徽章批 F2 引 HUD框架实装状态行佐证),v1.0 把它当实机可测层不成立 | AGENTS.md:68;git log d337c9e5;roadmap 迭代 25/28 行「残留人闸=目检」先例;`game/data/tables/board_gen.tres` 行段实查 | 契约 5 重写(阻塞闸全前置:T1 定性闸+契约 4;V4 改登记不阻塞+回补机制:否决→08 行回待做+06 记残留重开);F1 补两板型注;F10/T1 微光测面降为样张 v2 证据级别并注升级路径 |
**词面合规自查**:v1.1 全部新增/改写文本已按仓库现行用语规范禁词表逐词 grep 复扫,命中 0(他文档引文原貌除外);本次修订同时把卡片里 v1.0 残留的两处旧措辞换代为规范词。**v1.2 增补**:本次裁决留痕新增/改写文本同口径 grep 复扫,禁词命中 0。**v1.2 留档注**:下表 §11 中「Q2/Q3 保留待裁」「随 Q2/Q3 呈报交用户定序」「无既裁→中立化」均为 v1.1 时点的审查动作实录,不作现行状态读——2026-10-16 用户令已定案(Q3=甲·同批;Q2=延裁挂 T1 出口呈报硬步骤),现行裁决状态一律以 §10 为准。
@@ -158,7 +158,7 @@
**测试方式两分法**:V1-V9 归能力验证(自动化闸;对拍跑批沿用现役 sim-data/MC 设施,**跑批发起前须用户批准**——M4 同纪律);「全流程操作观感零变化」(菜单/营地/冒险/战斗逐屏走查)归正常流程体验=用户目检,登记 07 不阻塞。
**闸口径**:轻闸/重闸按 CLAUDE.md 分级周期口径;五波各自出口全绿才并下一波;批末四闸全绿才合并;测试执行两入口铁规不破。
**闸口径**:轻闸/重闸按 AGENTS.md 分级周期口径;五波各自出口全绿才并下一波;批末四闸全绿才合并;测试执行两入口铁规不破。
## 8. 异常分级
@@ -0,0 +1,230 @@
# 需求卡片:启动装配与生命周期验收补全批
- 版本:v1.0(2026-10-15 成文;计划书经用户批准,两裁点全落)
- 来源:用户计划书《启动装配与生命周期验收补全批 · 计划书》(2026-10-15 对话呈交并批准)+本卡 §2 代码级坏事实三件
- 归属:测试基建/工程债批(缺陷修复+验收补全;零玩法行为变更,装配顺序修复除外)
- 排期:**已编入迭代 28**(2026-10-15 用户令「迭代 28 插队」——M4 数值批占位行顺延 29+);**开工门=U0 已满足**(用户令「交卡后连做全批」=卡片预批;grilling 多轮复核门由用户预批豁免,实施期仍按复核审点自检「测什么/怎么测/谁验」三问,见 §10)
## 1. 目标与完成定义
把「启动后玩家该看到什么、状态对象何时该活何时该死」变成**可执行验收函数**:今后任何一笔改动犯同类错(装配序错/层被盖/对象早释放/时序倒置),闸必红。每条新验收函数以**变异验证**(故意改坏→看红→还原)证明拦截能力,**无变异红记录的断言不算验收成立**。
完成定义(六项,全绿方收口):
1. **坏事实三件修复并钉住**:装配顺序修复(冒险屏先挂、菜单屏后挂);V2 断言不再保护错误顺序;菜单截图有内容断言(探针自检+墨色判据+golden 三件)。
2. **装配语义合同单点化**:全视觉层顺序唯一事实源=单一合同常量;builder 的 add_child 与 register 同源派生。
3. **冒烟新增两段**:`_smoke_boot_chain`(boot 链路时序后置条件六断言)、`_smoke_lifecycle_matrix`(阶段×引用面存活性矩阵,十阶段全引用面)。
4. **渲染面三件**:shot_probe 两自检、shot_checker 墨色占比断言、启动态菜单 golden 入 render_gate。
5. **变异验证记录表**:每条新验收函数≥1 个缺陷类注入实验(变异点 file:line+跑的闸+红输出),落迭代实现报告。
6. **规范三处落文**:AGENTS.md 硬规则、code-conventions.md 测试节细则、req-card 技能验收闸。
批末四闸全绿(冒烟全量+run_all+probe_gate --click/--full+render_gate);冒烟断言数增量呈报;F5 实机目检登记 07(登记不阻塞)。
## 2. 现状事实(2026-10-15 代码级实查;开工自行复核)
### 2.1 坏事实一·装配顺序错(F5 见战斗界面)
- `main.gd:207-210`(_build_ui 内):先实例化菜单屏并 add_child(:207-208)、后实例化冒险屏并 add_child(:209-210)——树序后者绘制在上,冒险屏盖住菜单屏;启动态 `_start_overlay.visible=true`(:194)被遮,F5 直接见战斗界面。
- `main.gd:203-206` 注释把该顺序写成设计意图(「树序 = [菜单屏, 冒险屏, 模态层...]——层内先后零视觉差」)——与玩家可见事实相悖:菜单屏启动态必须可见。
- 启动链全貌(_ready,:174-197):ConfigDB 加载(:175-180,fail-fast)→ settings_store 加载+应用(:184-186)→ _build_ui(:191)→ _begin_session(false) 闲时会话(:192)→ _refresh_resume_button(:193)→ _start_overlay.visible=true(:194)→ DS_DEBUG 门控(:195-197)。
### 2.2 坏事实二·V2 断言保护 bug
- `smoke_all.gd:176-177`:`check(kids.find(main._menu_screen) == 0 and kids.find(main._adventure_screen) == 1, "V2 组合根树序=屏壳在前(menu@0 adventure@1——视觉共存对全模态在其上)")`——把错误顺序写成期望值;冒烟全绿与 F5 见战斗界面并存(测试在保护 bug)。
- 同段其余断言(:178-187:营地屏壳夹商店与设置层之间/冒险屏壳在全模态之下/句柄指向/闲时会话在座)均为正确保序类,本批只改 :176-177 一句及周边注释。
- 断言先改(对现役 bug 立红)→ 装配后改(转绿)——红转绿过程写进实现报告(🔴 契约 4)。
### 2.3 坏事实三·菜单截图无内容断言
- `shot_probe.gd`:启动态菜单截图段(:45-49——_meta 记 menu_title/menu_sub 全局矩形后 _snap("menu"));`_problems` 自检清单(:21)全程无「启动态顶层可见层=start_overlay」类断言——菜单被埋时探针仍绿。
- `shot_checker.py`:菜单段仅一条副标题对比度断言(:132-136)+帮助文腿已退役(:135-136 注);判据=WCAG≥4.5 且背景纹理幅度 std≤18(:59-77)——只判反差不判「字在」:被埋菜单坐标处若有亮光柱过反差线即放行。
- `render_gate.sh` 段①(:53-67):shot_probe 七屏+shot_checker A-D,无菜单内容判据、无 shot_menu golden 段。
### 2.4 合同常量基底与特殊插位(T1 设计面)
- 现役登记单点:`main.gd:378-379` 十二模态登记数组(legend/node/level_screen〔TAG_SCREEN_STATE〕/curio/end/shop/camp/settings/status/career/confirm/debug〔TAG_NON_LOCKING〕)——登记序=树序=z 序纪律(缺陷⑤)的现役单点,但只覆盖模态层,不含屏壳与全屏态。
- 特殊插位三处(合同必须显式数据化,禁散落 move_child):
- **level_screen**:住冒险屏壳内(main.gd:220 句柄指向;登记位夹 node 与 curio 之间,:256-258 注)——树序在模态之下、登记序在模态之间;boot 态隐藏(level_map_screen.gd:209,_init 内置 visible=false)。
- **camp_screen**:实例化后 move_child 插位(main.gd:264-268——add_child 后 move_child(_camp_screen, shop_overlay.get_index()+1));camp_overlay 为其成员(:266);屏壳=MOUSE_FILTER_IGNORE 纯容器(camp_screen.gd _ready),boot 态透明、无输入截获。
- **curio_overlay**:move_child 对位终局层之下(main.gd:291-293)。
- 全屏态两个:`_start_overlay`(菜单屏成员,main.gd:211)与 `_inter_overlay`(独立全屏过场层,main.gd:332-335;树序在确认弹窗之前,:337-338 注)。
- 三屏壳均全矩形 Control + MOUSE_FILTER_IGNORE 纯容器(menu_screen.gd/camp_screen.gd/adventure_screen.gd 各 _ready;三个 .tscn 均无 visible=false)——**诊断订正①:屏壳是容器不是视觉层**。「顶层可见层」断言必须遍历合同**内容层**(两全屏态+battle_root/level_screen 两容器+12 模态),禁把屏壳当选样——否则 boot 态自树顶向下第一个可见 Control 会命中透明的 camp 壳(camp_screen 树序在菜单之上),断言恒假。
### 2.5 boot 链路可断言面(T2 判据源)
六断言判据(headless 全可判):
1. ConfigDB.is_ready 且表已载(main.gd:175-180)。
2. 设置已应用:settings_store.apply()(main.gd:186)→ Master 总线 mute/volume_db(settings_store.gd:44-46)+UiKit.motion_scale=0.5/1.0(settings_store.gd:47)——断言=引擎态与 settings_store 现值一致。
3. `_start_overlay.visible == true`(main.gd:194)。
4. 续玩钮可见态 == SaveManager.has_breakpoint()(_refresh_resume_button,main.gd:448-456;_resume_btn=菜单屏 resumebtn,:308)。
5. run_scope 非空且 is_adventure==false(闲时会话,main.gd:192;run_scope.gd:13)。
6. DS_DEBUG 未设时调试浮窗隐藏(main.gd:195-197;debug_overlay 仅 DS_DEBUG=1 启动即开)。
### 2.6 生命周期存活性面(T3 判据源)
- 会话物化(迭代 27 T1):_begin_session(main.gd:166-171)——旧会话 queue_free(:168,全 main.gd 唯一销毁调用点,其余命中均为注释)+RunScope.new()+add_child;_ready 即建闲时会话永非 null(:56/:192)。
- 引用面全量清单(随会话更替而失效的面,共五个承载物):
- `_treasure_ui`:settlement/runner 两个现值 lambda(main.gd:234-235)。
- `_bonus`:6 个现值 lambda(meta/save_manager/adventure/runner/is_adventure/gp_summary,main.gd:296-300)。
- `_camp_pres`:3 个现值 lambda(meta/save_manager/runner,main.gd:313-315)。
- `_modal_flow`:4 个查询 Callable(start_visible/inter_visible/settlement/rows_empty,main.gd:364-367)。
- `_row_pacer`:**5 个视图句柄**(log_view/stage/board_zone/settlement_fx/board_view,row_pacer.gd:19-23)+2 Callable(refresh_request/pump_ended,:24-25;注入点 main.gd:224-230)——**诊断订正②:计划书枚举「6 视图句柄」,代码实查 5,以代码面为准**。
- `run_scope` 13 成员(run_scope.gd:10-22:adventure/runner/settlement/is_adventure/level_active/level_screen_active/boss_active/was_settling/hints_shown/settlement_stop_timer/pending_candidates/locked_click/last_gain_amount)。
- 现役 V3 断言(smoke_all.gd:193-246):开局建会话/放弃受理/终局到达/会话收束/局态旗复位/两连局零泄漏——本批矩阵在其上扩阶段×引用面,驱动复用不另起点击链。
- 收束路径:_on_battle_end_continue(main.gd:623-646)——_begin_session(false) 新闲时会话(:642)+_start_overlay.visible=true(:644)+续玩钮刷新(:645)。
- 终局面:_on_adventure_finished(main.gd:596-620)——settlement=null(:599)、_exit_level_screen(:600)、终局面板(:612-615)。
### 2.7 渲染闸与 golden 现状(T4 判据源)
- `golden_baseline_refresh.sh`:仅棋盘三张基线路径(board_shot_probe 抓帧→golden_board_crop.py 裁剪→game/tests/golden/ 三张,:30-41)——缺全屏基线刷新路径。
- `golden_compare.py`:支持任意同尺寸 PNG 对拍(render_gate.sh:129-130 现役用法;容差=灰度差≤16 且 changed≤2%,render_gate.sh:15 注)。
- `render_gate.sh` 段构成:①shot_probe 七屏+shot_checker(:53-67)②fx/board 取证(:69-105)③棋盘 golden(:107-136)④基准档 1280 单档(:17-19 注)。
- 菜单光柱:ui_assembler.gd:107 `UiKit.beams_rect()`(程序生成静态贴片;迭代 26 T4 连续 alpha 后仍为静态纹理);静态考证 menu_screen.tscn/ui_assembler.gd/menu_screen.gd 零 AnimationPlayer/ShaderMaterial/create_tween 命中——**运行期仍须帧差复核**(T4 前置验;非零则 golden 收窄左列文字/按钮区)。
- 菜单几何 meta 现役:shot_probe.gd:47-48(menu_title/menu_sub 全局矩形)——收窄区取样坐标源,禁硬编码像素。
### 2.8 冒烟与单测基线
1081/0(迭代 27 收口读数,roadmap 迭代 27 行;开工日以 active.md 快照复核);run_all 27 套(迭代 27 收口径)。
## 3. 设计契约(🔴 触碰=L3 停机呈报)
1. 🔴 **零玩法行为变更**:除装配顺序修复(本批行为修复本体)外,玩法/数值/逻辑零改动;对拍面=冒烟全量+探针结构断言零漂移;本批无数值改动,MC 零跑。
2. 🔴 **合同单点化**:全视觉层顺序唯一事实源=单一合同常量(屏壳序+两全屏态+12 模态一表);builder 的 add_child/move_child/register 必须同源派生;禁第二处硬编码层序(三处特殊插位必须经合同数据表达)。
3. 🔴 **断言禁裸下标**:「A 在 B 之上」类二元关系一律语义断言(find+序数比较/树遍历+visible+矩形判据);禁 `kids[0]==menu` 式裸下标(现役 smoke_all.gd:176 即反例)。
4. 🔴 **测试先行**:V2 断言先改(对现役 bug 立红)→ 装配后改(转绿);红转绿过程写进实现报告。
5. 🔴 **变异验证门槛**:每条新验收函数≥1 个对应缺陷类注入实验,走最窄闸见红;记录(变异点 file:line+闸+红输出)落实现报告;无变异红记录的断言不算验收成立。
6. 🔴 **只加不重构**:T1-T6 之外代码零触碰;shot_probe/shot_checker/golden 工具链只增不断(既有断言语义不窄化、既有基线不删除)。
7. 🔴 **闸机轮次纪律**:新断言先 standalone 直跑红/绿(30 秒级)→ 最窄确认 → 全批收口跑一次全套;禁修一处跑全套(AGENTS.md 闸机轮次纪律原文)。
## 4. 范围边界
**做**:T1-T6 六任务(§6)。
**不做**(去向):
- GDD 设计面零改动(反哺点除外——architecture 若因合同常量/启动链/生命周期矩阵产生陈述差,列反哺点呈裁,另批落文)。
- M4 数值批占位行内容零改动(只顺延编号 28+→29+)。
- 四类同类错(装配序错/层被盖/对象早释放/时序倒置)之外的玩法缺陷——另见另立,不顺手带。
- 顺手重构 T1-T6 之外代码(🔴 契约 6)。
- 既有 06 在册项(引擎原生控件键盘焦点/九宫格切片/对比度残余位等)与本批无关,不碰。
## 5. 关联文档同步面
| 文档 | 关联点 | 同步义务 |
|---|---|---|
| [roadmap](../../roadmap.md) | 迭代行:本批编入迭代 28(2026-10-15 用户令);原「迭代 28+」M4 占位行顺延改记 29+;「当前位置」节迭代进度/近期主战场两句更新 | **机械面,随批**(定义登记笔已落 master;收口 T6 换代) |
| [06-待办清单](../gdd/06-待办清单.md) | 新登记条:本卡片名/文件指针/状态(已编入) | **机械面,随批**(定义登记笔已落;收口按批结论销号或改写为反哺点登记) |
| [AGENTS.md](../../AGENTS.md) | 批次工作流「实施」段第 7/8 条(:102-103)旁:新增硬规则「验收函数无变异红记录不算验收成立」 | **机械面,随批**(T6) |
| [code-conventions](../dev/code-conventions.md) | §3 测试纪律(:108-144):补变异验证操作细则(注入实验设计/最窄闸跑法/记录格式) | **机械面,随批**(T6) |
| 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 反哺点节+变异验证记录表+冒烟断言数增量 | **机械面,随批**(收口时产出) |
| design/dev/architecture/architecture.md | 装配合同常量成为层序唯一事实源、boot 链路后置条件成文、run_scope 生命周期矩阵——若与现行陈述有差(iter27 反哺点在册:06 登记「场景分层/会话生命周期陈述滞后于实态」) | **反哺点**(列实现报告待用户裁决,另批落文;设计权威文档不随批更新) |
| [08-Alpha版本标准](../gdd/08-Alpha版本标准.md) | 测试基建四行(冒烟套件/单元测试套件/界面探针/机器可读的呈现断言,:128-132)状态不因本批改变——本批只加断言不加新设施类 | **无关联文档**(四行在役不变) |
## 6. 任务卡
### T0 开工基线与事实复核(≈0.25d)
1. 建独立 worktree(分支 iter28-bootlife-20261015);拷 `.godot/`+字体 `.import` 边车(worktree 缓存三件套;本批零素材依赖——artwork 不入 git 无涉)。
2. 基线三查:冒烟全绿数(现 1081/0)、run_all 套数(现 27)、探针现行绿面——对拍口径记档。
3. §2 全部 file:line 复核(含 2.4 三处特殊插位的运行期树序实采=合同常量现序真值;2.7 光柱静态结论复核)。
4. 计划书存档 `.zcode/plans/启动装配与生命周期验收补全批-loop-plan-2026-10-15.md`(中间产物,不入 git)。
### T1 装配语义合同+顺序修复+V2 断言重写(≈1.0d)
1. **合同常量**:单一有序表覆盖——屏壳序(冒险屏<菜单屏)、两全屏态(start/inter)、12 模态;三处特殊插位数据化(level_screen 宿主+登记 between node/curio;camp_screen after shop;curio before end);builder 从合同派生 add_child/move_child/register 全链(main.gd:202-268 装配段与 :378-379 登记段同源改写)。
2. **顺序修复**:冒险屏先挂、菜单屏后挂(main.gd:207-210 调序;:203-206 注释按新序改写)。
3. **V2 断言重写**(smoke_all.gd:176-177 及周边;尾缀〔装配生命批 V1〕):
- 删裸下标期望,新断言组:
- V1a 启动态顶层断言:boot 后遍历合同**内容层**(§2.4 诊断订正①——屏壳是容器不当候选),自树顶向下第一个可见层=start_overlay(headless 可判);
- V1b 语义关系:start_overlay 树序在 battle_root 之上(菜单屏在冒险屏之上);
- V1c 12 模态逐对保序(合同邻接对树序两两比较);
- V1d 登记序=树序逐对相等(ui_struct_probe.gd:330 career 专属断言推广到全部模态+屏壳层;level_screen/camp_screen 两特例经宿主/成员间接比较,写法见代拍板项 2)。
4. **变异项**(随 T5):翻装配序(菜单先挂)→V1a/V1b 红。
### T2 boot 链路(≈0.5d)
1. `_smoke_boot_chain` 新段,挂 `_split_tail`(smoke_all.gd:92 摘要行前;按 :88 协程纪律 await 调用)。
2. 六断言(§2.5;尾缀〔装配生命批 V2〕)。
3. **变异项**:续玩钮状态源倒置(visible=not has_breakpoint)→红。
### T3 生命周期矩阵(≈1.5d)
1. `_smoke_lifecycle_matrix` 新段(挂 _split_tail;尾缀〔装配生命批 V3〕)。
2. 十阶段(闲时/开局停点/地图选路/战斗中/结算后/终局面/回菜单收束/两连局/续玩断点/各模态开合后)× 五引用面(§2.6):回调逐个调用→命中对象 is_instance_valid 且符合该阶段存活态;专项判据——战斗中 settlement 活;_on_adventure_finished 后 settlement==null 且无悬挂;收束后旧局经 queue_free 消亡但 main.run_scope 已指向新闲时会话;_begin_session 后新会话即刻 is_inside_tree(无真空窗)。
3. 驱动复用:V3 debug seed 开局路径(smoke_all.gd:206-207 同款)+现役 _smoke_full_battle/_smoke_level 夹具;不另起点击链。
4. **变异项**:注释 _begin_session 的 add_child / 提前 queue_free→红。
### T4 渲染面(≈1.0d)
1. **shot_probe 两自检**(进 _problems;尾缀〔装配生命批 V4〕):①boot 态顶层可见全屏层=start_overlay(树遍历,判据同 V1a);②菜单标题/副标题 label is_visible_in_tree 且 rect 落屏内。
2. **shot_checker 墨色断言**(尾缀〔装配生命批 V5〕):菜单文字框内墨色像素占比在案(对比度只判反差、新判据判「字在」;墨色定义与阈值实施期按实测定 provisional,代拍板项 4)。
3. **菜单 golden**(尾缀〔装配生命批 V6〕):先验光柱帧差(§2.7——静态零动画在案,运行期复核:连续两帧光柱区像素差为 0)→golden_baseline_refresh.sh 扩全屏基线路径(shot_menu 启动态抓帧→game/tests/golden/menu_boot.png)→render_gate.sh 补 shot_menu 对比段;帧差非零=收窄左列文字/按钮区(menu_title/menu_sub meta 矩形外扩,禁硬编码像素),收窄不成立=L3。
4. **变异项**:藏菜单层(start_overlay.visible=false 或 move 到冒险屏下)→V1a/V4 红。
### T5 变异验证(≈0.5d,横切随批)
1. 每条新验收函数≥1 注入实验(T1-T4 各变异项),走最窄闸见红后还原。
2. 记录表落实现报告:变异点 file:line+跑的闸+红输出原文。
3. 随批同步,不集中补做。
### T6 规范落文+文档同步闸+收口(≈0.5d)
1. 三处规范落文:AGENTS.md 批次工作流实施段(:102-103 第 7/8 条旁)硬规则「验收函数无变异红记录不算验收成立」;code-conventions.md §3 测试节(:108-144)补变异验证操作细则;req-card 技能 §7 验证闸补同款要求。
2. §5 机械面更新完毕+反哺点逐条列明待裁决。
3. 批末四闸全绿(冒烟+run_all+probe_gate --click/--full+render_gate)。
4. 收口五步(active.md 快照/状态记录/roadmap 换代/批末闸留痕)+实现报告(含变异验证记录表+冒烟断言数增量呈报)。
5. F5 实机目检登记 07(主菜单顶层、按钮可点;登记不阻塞)。
**估时合计 ≈5.25d**(需求卡片 0.5d 已成文)。切分预案:T3 最可能超盒(矩阵组合面大)——先落五核心阶段(闲时/开局停点/战斗中/终局面/收束)全引用面+两连局,续玩断点/各模态开合两阶段与逐模态深回调面为续补位;**收口定义含十阶段全引用面,批末未齐=不收口,L3 呈报**。T4 菜单 golden 帧差非零且收窄不成立=L3。
## 7. 验证闸(逐需求点验收清单)
**能力验证(自动化;谁验=批末四闸闸机,全绿才合并)**:
| # | 需求点 | 测什么 | 怎么测(载体+落点) |
|---|---|---|---|
| R1 | 合同单点化(T1-1) | 合同常量覆盖全视觉层(屏壳序+两全屏态+12 模态);builder 的 add_child/move_child/register 同源派生;无第二处层序硬编码 | 冒烟结构断言(smoke_all.gd _smoke_scene_split 改版段:合同表层序==运行期树序全对,含三处特殊插位)+源码计数断言(main.gd 的 add_child/move_child 调用点数=合同派生点数——仿 _smoke_hygiene_gates 源码扫描范式,smoke_all.gd:108-143) |
| R2 | 装配顺序修复(T1-2) | boot 后自树顶向下第一个可见**内容层**=start_overlay(headless 可判;屏壳=容器不当候选,§2.4 订正①) | 冒烟 V1a/V1b(_smoke_scene_split 改版段或新 boot 段;树遍历+visible+全屏矩形判据) |
| R3 | V2 断言重写(T1-3) | 旧裸下标断言(smoke_all.gd:176-177)删除;新断言组 V1a-V1d 在位;红转绿过程有记录 | 冒烟断言换代+实现报告记录(🔴 契约 4) |
| R4 | 模态保序+登记序=树序(T1-3) | 12 模态逐对保序;登记序=树序逐对相等(level_screen/camp_screen 两特例经宿主/成员间接比较) | ui_struct_probe.gd 推广段(:330 career 契约模式扩全部模态)+冒烟 V1c/V1d |
| R5 | boot 链路(T2) | §2.5 六断言:ConfigDB 就绪+表载/设置已应用/start_overlay 可见/续玩钮态==断点档态/闲时会话/DS_DEBUG 未设浮窗隐藏 | 冒烟新段 _smoke_boot_chain(挂 _split_tail,协程纪律) |
| R6 | 生命周期矩阵(T3) | 十阶段×五引用面:回调可调用且命中对象 is_instance_valid+阶段存活态;四专项判据(战斗中 settlement 活/终局后 null 无悬挂/收束换会话/新会话无真空窗) | 冒烟新段 _smoke_lifecycle_matrix(复用 V3 驱动+现役夹具) |
| R7 | shot_probe 自检(T4-1) | boot 顶层可见层=start_overlay;菜单标题/副标题可见且 rect 落屏内 | 场景探针 game/smoke/shot_probe.gd(render_gate 段①窗口化跑) |
| R8 | shot_checker 墨色断言(T4-2) | 菜单文字框墨色像素占比在案(判「字在」) | tools/shot_checker.py 菜单段(render_gate 段①机检) |
| R9 | 菜单 golden(T4-3) | 启动态菜单全屏(或收窄区)逐像素对拍基线;render_gate 有 shot_menu 对比段 | tools/golden_baseline_refresh.sh 扩路径+render_gate.sh 新段+game/tests/golden/menu_boot.png |
| R10 | 规范落文(T6-1) | 三处落文在位可 grep:AGENTS.md 硬规则/code-conventions 细则/req-card 技能验收闸 | 机械核对(收口人工核对+doc 三闸零新增违例) |
**变异验证(T5;怎么测=人工注入+最窄闸;谁验=批末闸机跑红记录)**:
- R11 每条新验收函数≥1 缺陷类注入实验:翻装配序→R2/R3 红;注释 _begin_session/提前 free→R6 红;藏菜单层→R2/R7 红;续玩钮状态源倒置→R5 红。记录(变异点 file:line+闸+红输出)落实现报告变异验证记录表。
**测试方式两分法**:R1-R10 归能力验证(自动化闸——测试代码直调核心写口构造状态,冒烟现役做法);R11 归人工执行记录(不走常驻闸);F5 启动态目检(主菜单顶层、按钮可点)归正常流程体验=用户目检,登记 07 不阻塞。
**闸口径**:轻闸每轮(冒烟全量+ui_input_probe;触碰 presentation 加跑 ui_click_probe+ui_layout_probe);重闸批末(轻闸+probe_gate --click/--full+render_gate+run_all+doc 三闸+熵增闸);新断言先 standalone 直跑(🔴 契约 7)。
## 8. 异常分级
- L1(自救):断言键名/尾缀拼错、helper 取数错、golden 收窄矩形取值偏差——立红即修。
- L2(记录继续):墨色占比阈值初值不当(过严误红/过松漏判)——批内调值注记;T3 阶段驱动链比预期深——记录继续(收口定义不变)。
- L3(停机呈报):触碰 §3 任一红线;发现计划书事实面之外的第四件坏事实(如 inter_overlay 层序/续玩路径装配问题);菜单光柱帧差非零且收窄方案不成立(基线抖动无法稳定);冒烟基数与 active.md 快照不符且原因不明。
## 9. 代拍板白名单(超清单必呈报)
1. 合同常量的数据形态(有序数组+特例字段 vs 分层字典表——约束=单点化+同源派生,形态自选)。
2. 登记序=树序断言对 level_screen/camp_screen 特例的表达方式(经宿主屏壳/成员间接比较的具体写法)。
3. boot 顶层断言的「内容层」候选集构造方式(合同层过滤 vs 显式清单——约束=屏壳不当候选)。
4. shot_checker 墨色定义与占比阈值(灰度阈值取法;实施期按菜单文字实测定 provisional,终值列反哺点呈报)。
5. 菜单 golden 收窄区矩形取法(光柱动画时:menu_title/menu_sub meta 矩形外扩值,禁硬编码像素)。
6. 变异实验最小注入手段选型(注释/改值/visible=false/move_child——以能表达缺陷类且可还原为准)。
7. 新冒烟段挂载顺序(_smoke_scene_split 与 _smoke_run_lifecycle 之间或之后——以断言依赖为准)。
8. 计划书存档文件名(.zcode/plans/ 下命名,T0-4 已落)。
## 10. 待裁点
**零待裁点**(2026-10-15 用户两裁全落:①迭代编号=迭代 28 插队、M4 数值批顺延 29+;②执行范围=交卡后连做全批——卡片经用户预批,grilling 多轮复核门由用户预批豁免;实施期仍按 req-card 复核审点自检:逐需求点过「测什么/怎么测/谁验」三问——§7 表 R1-R11 逐条可答,无回炉项)。
**开工门=U0(已满足)**。收口=§5 同步闸+06 销号/改写+反哺点呈裁+实现报告。
@@ -318,7 +318,7 @@
### G7 验收 V 条可执行性(攻击面 7)
逐条对 `tools/` 实存脚本核:**V1 无工具**(方向稿留痕不可机检)→ 从「机检化」降级为件核;**V2 ①②④ = shot_checker B/C/D(+F)**,但 B 段只判 meta 登记的已知文字框、C 段只有战斗屏三点 → 标「须先扩取样点位」,**③焦点 = 人闸**(E 段明文);**V3 = 样张脚本机检段复用扩展+48 色新建**(全仓无 48 色工具,grep 零命中);**V4 五项中第 1 项可借既有断言、第 2 项须新建、第 3/4/5 项目检**;**V7 原写「跑 doc 三闸+熵增对基线」违反 CLAUDE.md:19/56「run_all_gates.sh 是唯一闸入口与唯一闸清单,文档禁另列清单」** → 改为指路该脚本,并声明本批零闸件增删。附带核实:`game/smoke/shot_probe.gd`、`tools/golden_compare.py`、`tools/golden_baseline_refresh.sh`、`tools/repo_structure_audit.py`、`tools/doc_link_audit.py` 均实存(07 无样张条目为实查所得,已注明本批首登)。
逐条对 `tools/` 实存脚本核:**V1 无工具**(方向稿留痕不可机检)→ 从「机检化」降级为件核;**V2 ①②④ = shot_checker B/C/D(+F)**,但 B 段只判 meta 登记的已知文字框、C 段只有战斗屏三点 → 标「须先扩取样点位」,**③焦点 = 人闸**(E 段明文);**V3 = 样张脚本机检段复用扩展+48 色新建**(全仓无 48 色工具,grep 零命中);**V4 五项中第 1 项可借既有断言、第 2 项须新建、第 3/4/5 项目检**;**V7 原写「跑 doc 三闸+熵增对基线」违反 AGENTS.md:19/59「run_all_gates.sh 是唯一闸入口与唯一闸清单,文档禁另列清单」** → 改为指路该脚本,并声明本批零闸件增删。附带核实:`game/smoke/shot_probe.gd`、`tools/golden_compare.py`、`tools/golden_baseline_refresh.sh`、`tools/repo_structure_audit.py`、`tools/doc_link_audit.py` 均实存(07 无样张条目为实查所得,已注明本批首登)。
### G8 红线自检:卡片有没有替用户拍板(攻击面 8)
@@ -2,11 +2,11 @@
- 版本:v2.0(2026-10-15 成文 v1.0 → v1.1 → v1.2 → v1.3 → v1.4 → v1.5 → **v2.0**)
- v1.1:①**CI 从未执行**(`git remote -v` 无输出)⇒ T1 主体由 CI 改为本地闸;②**用户立规:历史决策文档只是变更记录、不是架构文档** ⇒ 🔴 契约 5 重写为「历史决策文档不回改」,Q1 由「是否改决策文档」改为「在役架构事实如何**迁出**」,新增 Q7;③修正「smoke_all 不被执行」的错误表述(它本就在本地轻闸首项)。
- v1.2(用户令后执行态):①**用户裁「CI 没有用、后面也不用、不留死配置」** ⇒ `.github/workflows/` 全数删除(分支 `ci-removal-20261015`),CLAUDE.md 硬性红线立「不建/不留/不参考 CI 配置,改门禁只改本地闸」;本卡 T1④「CI 同步对齐」、T2「CI job 改名」、Q2「是否并入 CI」、§5 同步面 CI 行**全部删除**;②**架构事实源纪律已成文**(CLAUDE.md 硬性红线 + doc-conventions);③排期订正:迭代 28 位已被「启动装配与生命周期验收补全批」占用。
- v1.2(用户令后执行态):①**用户裁「CI 没有用、后面也不用、不留死配置」** ⇒ `.github/workflows/` 全数删除(分支 `ci-removal-20261015`),AGENTS.md 硬性红线立「不建/不留/不参考 CI 配置,改门禁只改本地闸」;本卡 T1④「CI 同步对齐」、T2「CI job 改名」、Q2「是否并入 CI」、§5 同步面 CI 行**全部删除**;②**架构事实源纪律已成文**(AGENTS.md 硬性红线 + doc-conventions);③排期订正:迭代 28 位已被「启动装配与生命周期验收补全批」占用。
- **v1.3(2026-10-15 用户令「放到迭代 29」)**:①排期定为 **迭代 29**;②新增 **§0 前置依赖与并行性**——裁决**串行**(须等 iter28 收口),四条依据,并标明**例外**(CI 清除 4 文件建议先行合并);③T0-③/T0-④ 加注「开工日重采基线 + 复核 iter28 是否已改过相关行」。
- **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 清除;⑤**订正死引用**:`CLAUDE.md:21/:106/:116` 与 §0 的 `:102-103`(文件已压到 71 行,节号不存在)、`.github/workflows/tests.yml`(F3/F5/F6 直引已删文件)、`golden_compare.py:11`(实际 :13);⑥**新增架构文档回写义务**:本批落地后须把「三条判定硬闸现行状态」矩阵的「缺失」改「在位」、S 表 S3/S5 随之更新(§5)。
- **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` 双技能审计产出)
- 归属:**测试基建批**(req-card §3:缺陷修复/工程债/**测试基建**/重构类工程需求凭 bug 证据或 06 在册条目直接写卡,**无设计定稿前置要求**——本批凭据即审计报告 A 类证据)
- 排期:**迭代 29**(2026-10-15 用户令;**2026-10-16 已写入 roadmap 迭代 29 行**——原「M4 顺延 29+」行随 M4 数值批废除改写为「迭代 30+ 位空」记录)。开工门=U0,须用户 `/iter` 发令。
@@ -19,14 +19,14 @@
| # | 冲突面 | 具体情况 |
|---|---|---|
| 1 | **`CLAUDE.md` 汇聚文件** | iter28 T6 要在「批次工作流」加硬规则;本批可能动「硬性红线」节与闸口径句。同一汇聚文件两批改,顺序一乱即互相覆盖 |
| 1 | **`AGENTS.md` 汇聚文件** | iter28 T6 要在「批次工作流」加硬规则;本批可能动「硬性红线」节与闸口径句。同一汇聚文件两批改,顺序一乱即互相覆盖 |
| 2 | **`game/smoke/` 是 iter28 主战场** | iter28 改 `smoke_all.gd` / `ui_struct_probe.gd` / `main.gd`;本批 T4 要在同目录新建 `screen_flow_probe.gd/.tscn`,T7 还要给 15 个游离脚本定性 |
| 3 | **基线读数会作废** | 卡片冻结的旧读数(冒烟 1086/套件 27/探针数)在 iter28 加断言后失效——T0 白冻结,V11 改前锚失去意义 |
| 4 | **`08-Alpha版本标准` 会自相矛盾** | iter28 写「测试基建四行状态不变——只加断言不加新设施类」;本批恰恰动测试设施本身。并行则该文档无法陈述真话 |
⇒ **串行裁决维持,但阻塞已解除**(iter28 已于 2026-10-15 入库)。**T0-③ 一律以开工日 master 当读数为基线**——卡片旧数字全部作废,§2.1 只留待填空表,不再写死预估值。
**⚠ 引用订正(2026-10-16)**:原依据里 `CLAUDE.md:102-103`(批次工作流)与 `:115-116`(硬性红线)两处行号**已失效**——该文件经 2026-10-15 规则文件审计批压到 71 行,纪律节现为「硬性红线」`:52-70`、闸口径在 `:19`/`:55-57`。**本卡一律不引 CLAUDE.md 行号,只引节名。**
**⚠ 引用订正(2026-10-16)**:原依据里 `AGENTS.md:102-103`(批次工作流)与 `:115-116`(硬性红线)两处行号**已失效**——该文件经 2026-10-15 规则文件审计批压缩,纪律节现为「硬性红线」(2026-10-19 根规则文件改名 `CLAUDE.md`→`AGENTS.md`,只改名未改行,现共 75 行;闸口径在 `:19`/`:59`)。**本卡一律不引 AGENTS.md 行号,只引节名。**
**例外段已作废**:原「CI 清除 4 文件先合并」的例外不再成立——`ci-removal-20261015` 分支**未合入**(其 ADR 定位两条已被 2026-10-15 决策文档体系废除取代,分支去留待用户裁)。其中 `game/tests/README.md` 的门禁节改写**改由本批 T2 自吃**(见 §2.2 F6)。**本批开工不依赖该分支。**
@@ -48,7 +48,7 @@
- 三层各有在册承载(L1 `unit/` 27 套 + 本批新增 7 套;L2 `integration/` 从 0 到 ≥1 套入 manifest;L3 `screen_flow_probe` 入轻闸默认段);
- 判定可靠的**同类缺陷一并清零**:8 件 PASS 串探针改退出码优先、`run_all`/`test_kit` 补断言下限与错误扫描、`static_scan` S3 静默空转修复;
- 术语订正落到机械面(本地闸脚本注释/README 索引与术语小节/`run_all.gd` 头注);**README 与 `run_all.gd` 的 CI 残留全数清除**(CI 已删,文档不得继续教人配 CI);
- 重闸 `tools/run_all_gates.sh` 全量跑批**全绿且回执零新增红**(现役唯一验收入口,见 `CLAUDE.md`「运行与验证」节);06 登记销号;反哺点列明待裁。
- 重闸 `tools/run_all_gates.sh` 全量跑批**全绿且回执零新增红**(现役唯一验收入口,见 `AGENTS.md`「运行与验证」节);06 登记销号;反哺点列明待裁。
---
@@ -95,10 +95,10 @@
| F5' | 全库 `change_scene` **零命中**(项目走三屏壳 `visible` 互斥)。T4 可沿两处现成断言源:`smoke_all._smoke_scene_split()` 与 `ui_click_probe._exit_level_screen` | `smoke_all.gd:157`;`ui_click_probe.gd:483,503` |
| F6' | **CI 残留(CI 已删,文档仍在教人配 CI)**:`game/tests/README.md` 6 处(头注 CI/gdUnit4 行、目录布局「CI 冒烟统一入口」、Running「CI 调用点」「CI 旁必须配外部 wall-clock 超时」、Static Scan「提交前双跑:本地+CI」、`## CI` 整节含 gdUnit4 安装说明)+`run_all.gd` 头注 2 处(:2「CI 侧包装外部超时」、:7「由 CI/轻闸单独步骤调用」)。README 另记「18 套件」(现 27) | `README.md:4,5,16,33,39-40,68,73-77`;`run_all.gd:2,7` |
| F7' | `integration/` **不存在**(空壳已删)。README 章程登记四类集成用例(Core-Core/回放确定性/存档⇄RNG 往返/A1×A2 端到端),并注「各 GDD 登记的 deferral 集成用例以对侧登记为生效条件」 | `game/tests/`;`README.md:20` |
| F8' | `game/smoke/` 29 个 `.gd` 中 **17 个无 `.tscn` 宿主**(除 `smoke_all`/`probe_ui_util` 外 15 个待定性):adventure_monte_carlo、auto_player、battle_driver、board_stat_probe、calibrate_boards、damage_probe、defense_scan、dump_battle、experiment_density、level_autoplay、monte_carlo、reward_expectation、rhythm_batch、skill_rhythm_probe、verifier_batch。⚠ **其中 `adventure_monte_carlo`(parity 载体)与 `verifier_batch`(balance_verifier 采集端)是 `CLAUDE.md`「运行与验证」登录在册的手动入口,禁当死件退役** | `game/smoke/`;`CLAUDE.md`「运行与验证」节 |
| F8' | `game/smoke/` 29 个 `.gd` 中 **17 个无 `.tscn` 宿主**(除 `smoke_all`/`probe_ui_util` 外 15 个待定性):adventure_monte_carlo、auto_player、battle_driver、board_stat_probe、calibrate_boards、damage_probe、defense_scan、dump_battle、experiment_density、level_autoplay、monte_carlo、reward_expectation、rhythm_batch、skill_rhythm_probe、verifier_batch。⚠ **其中 `adventure_monte_carlo`(parity 载体)与 `verifier_batch`(balance_verifier 采集端)是 `AGENTS.md`「运行与验证」登录在册的手动入口,禁当死件退役** | `game/smoke/`;`AGENTS.md`「运行与验证」节 |
| F9' | golden 视觉基线冻结于 **2026-09-30**(v3.5 视觉落码后),工具头注已载「资产升档批换代时显式重制基准」 | `tools/golden_compare.py:13` |
| F10' | **S3 静默空转**:`static_scan.sh` 的 S3 扫裸路径 `core`——仓根无此目录(实际 `game/core`;iter27 T5 修过整个脚本的 cd 基线却漏此路径)⇒ 恒零命中恒绿、什么都不扫。架构文档 S 表已登记「未落地…现行实跑恒零命中」;该规则守的是**数值单一事实源**红线 | `game/tests/static_scan.sh` S3 段 |
| F11' | `parity_anchor.py` 载体=`adventure_monte_carlo.gd` 同种子 20 局×3 变体(base/attune/shop)RUNSUM+JSONL 双面字节级对拍;**不在任何闸表**;调的正是 MC 脚本(受 `CLAUDE.md`「MC/模拟:无数值改动零跑」红线管辖) | `tools/parity_anchor.py:1-23` |
| F11' | `parity_anchor.py` 载体=`adventure_monte_carlo.gd` 同种子 20 局×3 变体(base/attune/shop)RUNSUM+JSONL 双面字节级对拍;**不在任何闸表**;调的正是 MC 脚本(受 `AGENTS.md`「MC/模拟:无数值改动零跑」红线管辖) | `tools/parity_anchor.py:1-23` |
> **灾害先例(只留指针,不复制事实)**:GDScript 运行时脚本错误不改退出码、不计失败数、静默中断所在函数剩余断言——2026-09-19 实证「309 项 0 失败」实为断言未跑全,沿革见 `architecture.md:157` 与 git 提交史。这是 SCRIPT ERROR 扫描必须存在于判定层的理由。
@@ -151,7 +151,7 @@
| `game/tests/run_all.gd` | manifest 增 7 套件 + 集成件(expect 协议扩);`_run_suite` 增断言数校验与错误扫描;`example_test` 摘除;**头注 CI 残留 2 处清除** | **机械面·随批更新** |
| `game/tests/unit/test_kit.gd` | `finish()` 零断言判红 | **机械面·随批更新** |
| `game/tests/README.md` | 目录布局增 `integration/`;「逻辑冒烟」→「单元套件」;**CI 残留 6 处全清(门禁节改本地闸口径)**;断言计数双口径与「18 套件」按开工日读数;新增术语小节(冒烟=秒级存活检查)+游离脚本台账节+新区类型标注示例 | **机械面·随批更新**(T2,+0.25d) |
| `CLAUDE.md` | 「运行与验证」节轻/重闸口径句(**不引行号**——文件已压到 71 行):仅当 T4 入闸改变分级口径时才改 | **机械面·视需要更新** |
| `AGENTS.md` | 「运行与验证」节轻/重闸口径句(**不引行号**——文件已压到 71 行):仅当 T4 入闸改变分级口径时才改 | **机械面·视需要更新** |
| `tools/run_all_gates.sh` | 新增「回放确定性对拍」**条件闸件**(diff 触面判定 + 未触面 SKIP 记回执) | **闸清单唯一定义处·随批更新**(禁在文档另列清单) |
| `game/tests/static_scan.sh` | **S3 路径修正 + 零命中自检**;补 S5 规则(视余量 S6) | **机械面·随批更新** |
| `design/dev/architecture/architecture.md`「测试与质量域」节 | ①**「三条判定硬闸现行状态」矩阵**:落地后把 run_all/probe_gate/render_gate 的「缺失」改「在位」;②**S1–S8 表**:S3 改「在位(路径修正后)」、S5 若落地改「在位」;③五模块归属表的判定口径列随之更新 | **必做·随批回写**(v2.0 新增义务——事实源必须在批末反映真实状态) |
@@ -165,7 +165,7 @@
## 6. 任务卡
> 估时按 Claude 工作日口径;每卡出口自跑轻闸,全批出口跑重闸 `tools/run_all_gates.sh`(`CLAUDE.md`「运行与验证」节)。
> 估时按 Claude 工作日口径;每卡出口自跑轻闸,全批出口跑重闸 `tools/run_all_gates.sh`(`AGENTS.md`「运行与验证」节)。
### T0 证据坐实与基线冻结(≈0.5–1d,**必先做**)
@@ -188,7 +188,7 @@
> 前提:历史决策文档不回改(🔴 契约 5)。本节只改机械面文本。
- `run_all.gd` / `README.md` / `CLAUDE.md` 口径句中「逻辑冒烟」→「单元套件」。
- `run_all.gd` / `README.md` / `AGENTS.md` 口径句中「逻辑冒烟」→「单元套件」。
- 定义「冒烟(smoke)」在项目内的**唯一保留语义=秒级存活检查**(能否启动、能否加载表、能否进主屏),写进 README 术语小节;同步写明 `run_smoke.py` 之名是历史遗留、**其承载的是系统级断言面**(改名与否走 Q7)。
- **CI 残留清除 8 处**(Q8 甲,本批自吃):`README.md` 6 处(头注 CI/gdUnit4、「CI 冒烟统一入口」、「CI 调用点」、「CI 旁必须配外部 wall-clock 超时」、「提交前双跑:本地+CI」、`## CI` 整节)+ `run_all.gd` 头注 2 处。门禁节同步改本地闸口径。**不等 `ci-removal` 分支。**
@@ -242,7 +242,7 @@
| V1 | 三硬闸-退出码 | **反例实证**:探针打印 PASS 后 `quit(1)` → 闸判红(8 件改完后逐段验) | T0-① 留档 + T1 探针判定段,新增进 probe_gate 自检 |
| V2 | 三硬闸-脚本错误 | **反例实证**:注入一处 `Parse Error` 的套件 → 闸判红(而非绿) | 新增闸件单测(进 `run_all`) |
| V3 | 三硬闸-断言下限 | **反例实证**:零断言套件 → 判红 | `test_kit.finish` 断言 + `run_all` 套件数校验 |
| V4 | 术语订正(机械面) | 本地闸脚本注释 / README 术语小节 / `CLAUDE.md` 口径句 到位;「冒烟=秒级存活检查」定义小节在册;**README 与 `run_all.gd` 的 CI 措辞零命中** | 源码断言(grep 旧措辞零命中) |
| V4 | 术语订正(机械面) | 本地闸脚本注释 / README 术语小节 / `AGENTS.md` 口径句 到位;「冒烟=秒级存活检查」定义小节在册;**README 与 `run_all.gd` 的 CI 措辞零命中** | 源码断言(grep 旧措辞零命中) |
| V5 | L2 承载 | `integration/` 在册 + ≥1 套进 manifest;**parity 条件闸件入 `run_all_gates.sh`,触面批实跑一次、非触面批正确 SKIP** | 新集成套进 `run_all`;条件闸件进重闸 |
| V6 | L2 存档往返 | 存→读→同种子续跑,与未存档一路输出逐位一致 | 新集成套断言 |
| V7 | L3 屏切换 | 六步主流程 + 三屏壳 `visible` 互斥(任意时刻 ≤1 可见)+ 放弃回退路径 | 新探针 `screen_flow_probe`,**入轻闸默认段** |
@@ -253,7 +253,7 @@
**测试方式两分法**:V1–V11 全部归**能力验证**(自动化闸,调试接口沿用现役 DebugOverlay/DS_DEBUG 门控);本批**无用户目检项**(纯基建,不改变玩家可见行为)——若 T7 golden 判失效需重制,该处置登记 07 观测项并呈报。
**闸口径**:轻闸=`tools/run_all_gates.sh --quick`,重闸=全量并写回执(`CLAUDE.md`「运行与验证」节);每卡出口自跑轻闸(触碰 presentation 加跑 ui_click);测试执行两入口铁规不破(开工后属迭代 loop 入口,跑测合法);MC/统计类跑批仍须用户批准,对拍按条件闸件跑(契约 7)。
**闸口径**:轻闸=`tools/run_all_gates.sh --quick`,重闸=全量并写回执(`AGENTS.md`「运行与验证」节);每卡出口自跑轻闸(触碰 presentation 加跑 ui_click);测试执行两入口铁规不破(开工后属迭代 loop 入口,跑测合法);MC/统计类跑批仍须用户批准,对拍按条件闸件跑(契约 7)。
---
@@ -274,7 +274,7 @@
5. 新单测/新探针的文件命名与落点(不违背 code-conventions 命名纪律前提下)。
6. 4 个 core 模块单测的断言面取舍(覆盖到什么粒度)。
7. **断言本身写错且与现行设计冲突**时的修法(契约 1 的唯一例外:须在报告中逐条列明改了哪条断言、依据哪份设计)。
8. 游离脚本「在役/失效」的判定(存疑者按在役登记并标注;`CLAUDE.md` 在册入口禁当死件)。
8. 游离脚本「在役/失效」的判定(存疑者按在役登记并标注;`AGENTS.md` 在册入口禁当死件)。
9. S5 规则的正反例 fixture 构造方式。
10. 提交切分与 worktree 分支命名(走既有 worktree 纪律)。
11. **S3 零命中自检的实现形态**(如何判定「扫描面为空」:目录存在性校验 + 命中数为 0 的显式标注)。
@@ -292,10 +292,10 @@
| **Q4** | `integration/` runner 形态 | **甲**:并入 `run_all` manifest(零新机制) |
| **Q5** | S9 类型闸是否收回 smoke/tests 豁免 | **甲+**:存量豁免维持;**本批新写测试件全类型标注**(升 🔴 契约 8) |
| **Q6** | golden 基线若判失效如何处置 | **甲**:显式重制 + 呈报 + 复闸(iter26 T6 先例);**先判再动、禁先动后判** |
| **Q7** | `run_smoke.py`/`smoke_all.gd` 是否改名 | **甲**:不改名,README/CLAUDE.md 加注「名是历史遗留,实为系统级断言面」 |
| **Q7** | `run_smoke.py`/`smoke_all.gd` 是否改名 | **甲**:不改名,README/AGENTS.md 加注「名是历史遗留,实为系统级断言面」 |
| **Q8**(第二轮) | README/`run_all.gd` 的 CI 残留 8 处归谁 | **甲**:本批 T2 吸收(+0.25d);**不等 `ci-removal` 分支** |
| **Q9**(第二轮) | T5 补洞选面 | **甲+更正**:维持四 core 选面,但 `status_container` 已证非空覆盖 → 换 **`board_generator`**;余下 3 个真零指名(`board_data`/`reward_economy`/`skill_lottery`)登记 06 |
| **Q10**(第二轮) | 游离脚本存疑默认 | **甲**:存疑按在役登记并标注;`CLAUDE.md` 在册入口(`adventure_monte_carlo`/`verifier_batch`)禁当死件 |
| **Q10**(第二轮) | 游离脚本存疑默认 | **甲**:存疑按在役登记并标注;`AGENTS.md` 在册入口(`adventure_monte_carlo`/`verifier_batch`)禁当死件 |
| **Q11**(第二轮) | v2.0 重核时机 | **甲**:U0 前只读重核(已完),裁点落定后一次性升版=本版 |
| **N1**(第二轮) | 卡片 §2 自持事实表 vs 架构文档 | **甲**:§2 改指针,事实面归 `architecture.md` 三张表 |
| **N2**(第二轮) | T6 是否收 S3 路径修正 | **甲**:收(+0.25d),含零命中自检 |
@@ -100,7 +100,7 @@
| F11 | 图鉴内容在册挂起:奖励格图鉴柜台已随配比预设批整体挂起冻结(2026-10-05 用户令,06 在册),重启须用户另行发令——本批只改入口不激活内容 | `design/gdd/systems/跨局循环/生涯.md:63` |
| F12 | 贴图重构批搁置未废:营地与元进度件终稿置换(06:21-27)等交互重做定形后再议(澄清③1/§⑧5)——本批不清偿该债;四柜台拆解后原「柜台场景贴图」债对象变化,随该批重新评估 | `design/gdd/06-待办清单.md:21-27`;`需求澄清-营地交互重做-2026-10-18.md` §③1/§⑧5 |
| F13 | 营地底栏「最近冒险」条带与生涯历史回看同源(同一份 `recent_summaries`),其去留=生涯.md P6 待裁点(期二必答)——CampOverlay 拆解后该条带无处挂,P6 被迫提前面对(本卡 Q4) | `camp_overlay_view.gd:186-189`/:536-549;`生涯.md:69`/:91-101\` |
| F14 | 素材线纪律:`artwork/` 不入 git(`.gitignore:51` 忽略行)——批次 worktree 内无该目录、主工作区 D:/code/g-plan2 实体存在(在途工作区);涉素材脚本须传主区绝对路径否则静默 0 张;素材替换前先归档旧档;终稿归 `game/assets/art/` | `CLAUDE.md:32`;`.gitignore:51`;art-bible §8.3 归档纪律(v1.1 行号与表述订正) |
| F14 | 素材线纪律:`artwork/` 不入 git(`.gitignore:51` 忽略行)——批次 worktree 内无该目录、主工作区 D:/code/g-plan2 实体存在(在途工作区);涉素材脚本须传主区绝对路径否则静默 0 张;素材替换前先归档旧档;终稿归 `game/assets/art/` | `AGENTS.md:32`;`.gitignore:51`;art-bible §8.3 归档纪律(v1.1 行号与表述订正) |
| F15 | 美术硬约束继续有效(澄清③4):明亮轻快像素风、**48 色板、HSV 300°–345° 禁入带、语义色纪律、WCAG ≥4.5:1**——全局约束,不在本讨论范围翻案 | `需求澄清-营地交互重做-2026-10-18.md` §③4 |
| F16 | 像素级规格不在本卡硬定(澄清③5):尺寸档/色板/明度档归「战斗一屏样张批」冻结的规格清单——该批现列 06「待设计」未排期(2026-10-17 用户令自迭代 30 剔除),本卡只写指针并登记依赖(缺口连带裁=Q6) | `需求澄清-营地交互重做-2026-10-18.md` §③5;`design/gdd/06-待办清单.md`(迭代 30 剔除卡②③ 条) |
| F17 | 机检工具面(v1.1 订正):**截屏级 48 色计数不在役**;在役=`tools/palette_check.py`(art-bible §8.3①挂点——48 设计色板令牌+新增色双门)+`tools/standee_asset_check.py`(像素画单张 32 色冻结执法);`tools/render_gate.sh`(shot_probe 七屏→shot_checker 语义断言;golden 段=棋盘三张+menu_boot 四张,**无 camp golden**——shot_checker.py:143 明载「camp/level 走骨架+目检清单」);shot_checker 段=屏级骨架/文字 WCAG/明度三档带/文字禁压纹理/文字在判据 | `tools/palette_check.py`;`tools/standee_asset_check.py`;`tools/render_gate.sh`;`tools/shot_checker.py:143` |
+1 -1
View File
@@ -278,7 +278,7 @@ Godot_v4.7.2-stable_win64_console.exe --headless --path . --script res://smoke/a
## 2026-09-12 呈现层 code-review 修复批(/code-review CHANGES REQUIRED → 全项清偿)
**触发**:全切片 53 脚本 ~9400 行 /code-review(CLAUDE.md 代码规范 + 架构文档对照),裁决 CHANGES REQUIRED(7 项必改)。core/ 12 文件与 smoke 断言面整体健康;病灶集中于 tune_panel 封装破口、main.gd 结构回涨、三处呈现契约错位。
**触发**:全切片 53 脚本 ~9400 行 /code-review(AGENTS.md 代码规范 + 架构文档对照),裁决 CHANGES REQUIRED(7 项必改)。core/ 12 文件与 smoke 断言面整体健康;病灶集中于 tune_panel 封装破口、main.gd 结构回涨、三处呈现契约错位。
**BLOCKING 修复**:
+3 -3
View File
@@ -88,9 +88,9 @@ timeout 120s godot --headless --script tests/run_all.gd
| 脚本 | 定性 | 用途与触发方式 | 结果由谁判 |
|---|---|---|---|
| `adventure_monte_carlo.gd` | **在役**(`CLAUDE.md` 在册入口) | 全冒险期望 MC;`tools/parity_anchor.py` 的对拍载体 | 工具脚本逐位比对 |
| `verifier_batch.gd` | **在役**(`CLAUDE.md` 在册入口) | `tools/balance_verifier.py` 的采集端(数值验证) | 报告落 `design/qa/` |
| `reward_expectation.gd` | **在役**(`CLAUDE.md` 在册入口) | 奖励期望测量(非封锁格分布/资源类型频次) | 人工读 stdout |
| `adventure_monte_carlo.gd` | **在役**(`AGENTS.md` 在册入口) | 全冒险期望 MC;`tools/parity_anchor.py` 的对拍载体 | 工具脚本逐位比对 |
| `verifier_batch.gd` | **在役**(`AGENTS.md` 在册入口) | `tools/balance_verifier.py` 的采集端(数值验证) | 报告落 `design/qa/` |
| `reward_expectation.gd` | **在役**(`AGENTS.md` 在册入口) | 奖励期望测量(非封锁格分布/资源类型频次) | 人工读 stdout |
| `monte_carlo.gd` | 在役 | 战斗期望 MC(胜轮数/承伤/清图/开格分布) | 人工读 stdout |
| `auto_player.gd` | 在役(库件) | 自动玩家策略单一实现——被 `battle_driver` preload | 宿主脚本 |
| `battle_driver.gd` | 在役(库件) | 战斗驱动;被 `damage_probe` preload | 宿主脚本 |
+1 -1
View File
@@ -86,7 +86,7 @@
2. **T0 开工**:建 worktree + 基线复读记档(冒烟/探针/三闸/MC 对拍基准)+ `git status` 归属核对(并行遗留只标旗不碰)。
3. **循环骨架**:一轮 = 一个任务卡——读卡 → 对事实源 → 实装 → 轻闸全绿 → 提交(代拍板随 commit 记录)→ 状态记录追加(查撞号)→ 下一轮。单 worktree 多点提交一次合并;轮内禁开第二个 worktree;基线每轮开工时点重测;断点续跑 = `git log` 对任务卡定轮次 + 重跑当轮轻闸。
4. **轻闸**(每轮必跑,headless):`tools/run_all_gates.sh --quick`(迭代中段自检档)。
5. **重闸**(批末 Tn):`tools/run_all_gates.sh` **按本批改动域跑**(触及 `game/` → `--code`,这是代码域唯一触发;不触及 `game/` 的一切路径 → `--docs`;一次改动同批混触两域 → 不带参数全量),所选域全绿——闸件清单、顺序与域划分只在该脚本里定义,本文件与 CLAUDE.md/规约均不另列;改闸件自身(`tools/` 下机检脚本与闸壳)不占合回全量,质量义务=落批时的变异验证;涉核心的 MC 与基线逐位比对、素材批的机检断言另行。
5. **重闸**(批末 Tn):`tools/run_all_gates.sh` **按本批改动域跑**(触及 `game/` → `--code`,这是代码域唯一触发;不触及 `game/` 的一切路径 → `--docs`;一次改动同批混触两域 → 不带参数全量),所选域全绿——闸件清单、顺序与域划分只在该脚本里定义,本文件与 AGENTS.md/规约均不另列;改闸件自身(`tools/` 下机检脚本与闸壳)不占合回全量,质量义务=落批时的变异验证;涉核心的 MC 与基线逐位比对、素材批的机检断言另行。
6. **人闸**(停机交付):真人目检清单 + 代拍板追认清单 + 异步终审触点(样张类)——本循环内唯一必经人审。
7. **异常分级**:L1 自救(一次重试)→ L2 记录继续(连续 3 次同红灯升级)→ L3 停机写报告等用户。
8. **批次完成后的五步登记**:①06 条目状态按 doc-conventions §12.1 推进(做完整条删除)②本文件顶部「当前位」三行换代,涉及里程碑移动时同步里程碑表 ③**实现批禁写本文件与 `design/`**(2026-10-17 用户裁:代码实现批只准写 `reports/`),该改哪一行写进 `reports/iter<N>-反哺点-<日期>.md`,由文档批执行 ④阶段变更改 stage.txt ⑤批末闸序列**按本批改动域**全绿留痕(回执 commit 对齐分支尖)。
+1 -1
View File
@@ -1,6 +1,6 @@
# sim-data — MC 缓存层
> 2026-10-03 立规:本目录整目录不入 git(根 .gitignore 强制)。语义=蒙特卡洛模拟试玩的磁盘缓存——最新一份 MC 锚+读数常驻留盘供分析直读,**无数值调整禁重跑**(触发细则见 CLAUDE.md「测试执行两入口铁规」MC 触发细则节)。
> 2026-10-03 立规:本目录整目录不入 git(根 .gitignore 强制)。语义=蒙特卡洛模拟试玩的磁盘缓存——最新一份 MC 锚+读数常驻留盘供分析直读,**无数值调整禁重跑**(触发细则见 AGENTS.md「测试执行两入口铁规」MC 触发细则节)。
## 现行锚(分析取数唯一入口)
+1 -1
View File
@@ -46,7 +46,7 @@ SOURCE_RULE_DATE = (2026, 10, 18) # req-card §2:设计事实源必填
SOURCE_MARKS = ("设计事实源", "唯一事实源") # 两种合格写法,与库内既有卡片实际形态对齐
SYNC_HEADING_RE = re.compile(r"^#{2,3}\s*\d*\.?\s*关联文档同步面")
BANNED_DOC_MARKS = ("design/", "../gdd/", "../registry/", "../research/", "../qa/",
"../dev/", "../ux/", "../art/", "roadmap.md", "CLAUDE.md")
"../dev/", "../ux/", "../art/", "roadmap.md", "AGENTS.md")
DATE_RE = re.compile(r"\d{4}-\d{2}-\d{2}")
VER_RE = re.compile(r"[vV]\d+(?:\.\d+)*")
+6 -6
View File
@@ -6,14 +6,14 @@
把目录三层裁定变成机器检查——任何会话乱放文件,收口时此处直接 FAIL。
四查:
1. 顶层目录白名单(新增顶层目录 = FAIL,须同批改 CLAUDE.md + 本脚本白名单)
1. 顶层目录白名单(新增顶层目录 = FAIL,须同批改 AGENTS.md + 本脚本白名单)
2. 根目录文件白名单(根上只许运行文件与规则文件)
3. 图像白名单(图只许在 artwork/ game/assets/ design/art/references/ design/dev/architecture/)
4. 退役路径守卫(production/ docs/ tests/ qa-data/ candidates/mockups 旧路径再现 = FAIL)
用法: python tools/repo_structure_audit.py # 全查,FAIL 时 exit 1
python tools/repo_structure_audit.py --json # 机器读输出
依据: CLAUDE.md「Project Layout」节(2026-09-27 目录三层收敛终态)。
依据: AGENTS.md「Project Layout」节(2026-09-27 目录三层收敛终态)。
"""
import sys
from pathlib import Path
@@ -25,7 +25,7 @@ ROOT = Path(__file__).resolve().parent.parent
# 清单的家——实现批只准往这里写,design/ 全目录对它只读。只放 .md,不放图(图像白名单不含此目录)。
TOP_DIRS = {"archive", "artwork", "design", "game", "sim-data", "tools", "reports"}
# 2) 根目录文件白名单
ROOT_FILES = {"CLAUDE.md", "roadmap.md", "stage.txt", "review-mode.txt",
ROOT_FILES = {"AGENTS.md", "roadmap.md", "stage.txt", "review-mode.txt",
".gitignore", ".zcodeignore"}
# 3) 图像允许目录(相对路径前缀;archive/ 为归档 zip 不扫)
# design/qa/ 收编(迭代 5 返工批 2026-09-29——U2 目检预览图/QA 呈现产物归位,commit 留痕)
@@ -49,7 +49,7 @@ def scan():
top_dirs = {p.name for p in ROOT.iterdir() if p.is_dir() and not p.name.startswith(".")}
extra = top_dirs - TOP_DIRS
if extra:
fails.append("顶层目录越界: %s(新增顶层目录须同批改 CLAUDE.md Project Layout + 本脚本 TOP_DIRS)" % sorted(extra))
fails.append("顶层目录越界: %s(新增顶层目录须同批改 AGENTS.md Project Layout + 本脚本 TOP_DIRS)" % sorted(extra))
# 2) 根目录文件(点开头忽略:.gitignore/.zcodeignore 白名单收编,.git 指针等本就不可见)
top_files = {p.name for p in ROOT.iterdir() if p.is_file() and not p.name.startswith(".")}
@@ -73,7 +73,7 @@ def scan():
# 4) 退役路径
for rel in RETIRED:
if (ROOT / rel).exists():
fails.append("退役路径再现: %s/(该目录已消亡,内容按 CLAUDE.md 终态归属;此路径出现即结构回潮)" % rel)
fails.append("退役路径再现: %s/(该目录已消亡,内容按 AGENTS.md 终态归属;此路径出现即结构回潮)" % rel)
# 5) design/ 一级子目录
design_subs = {p.name for p in (ROOT / "design").iterdir() if p.is_dir()} if (ROOT / "design").is_dir() else set()
@@ -95,7 +95,7 @@ def main():
print("\n【结构违例】×%d" % len(fails))
for f in fails:
print(" ! " + f)
print("\n处理: 文件归位到合法区;确需新类别 = 同批修订 CLAUDE.md Project Layout + 本脚本白名单,commit 留痕。")
print("\n处理: 文件归位到合法区;确需新类别 = 同批修订 AGENTS.md Project Layout + 本脚本白名单,commit 留痕。")
sys.exit(1)
print("\n结构审计 PASS(四查全过:顶层目录/根文件/图像白名单/退役路径)")
sys.exit(0)