判据(对 869 个 ZCode 会话与 16 个 Qoder 会话的读写统计):active.md 被整文件读 448 次、 单次中位数 14 KB、累计 6.09 MB 进上下文,311/320 个碰它的会话把它当第一个工具调用读; 但 7311 个提及它的思考片段的语境分布是——写入与编号簿记 327 个会话、并行冲突与避让 234 个、 退役与失真核对 162 个,而明确写「从它所载内容得知某事实」的只有 20 个会话。 逐条核 41 个条目:独特且现行 2 条(另 3 个子句)、别处已有权威源 14 条、陈旧或自相矛盾 7 条、 已完结批次的历史叙述 18 条;按字节约 95% 属后三类。失实样本:architecture 版本记 v1.6 实为 v1.8、 规则文件数记 7 份实为 6 份、迭代 27/28 记「位预留追加卡」而 roadmap 记已完成、三个已删 worktree 仍记「在盘待删」、同一条既宣称「文档禁列闸清单」又自行列出 01–11 全套闸。 执法件已建一轮仍拦不住:08b 体量闸只测条目数/行数/编号/死链,测不出语义失真;钩子不随仓库传播, 只有 ZCode 在跑;10-15 清到 8.6 KB、10-17 回到 40 KB,用户为「只写不删」连续三次发火。 改动面: - 删 active.md 与 tools/audit_active_state.py;run_all_gates.sh 摘除 08b 闸件与头注、 baseline.json 删 08b 记录(现存 12 闸)、repo_structure_audit.py 根文件白名单去 active.md - doc-conventions §10 改写为「仓库根不设状态文件」并留裁决与判据(保持 §11/§12 编号不漂); §11 表两行去状态文件口径;§4 适用范围去 active.md - process-conventions §1 第 2/3 条(合回前查尾号防撞号、豁免面)、§3 第 12 条(批次完成后的 登记义务)、§6 分级周期口径(闸件清单不再在文档重列)四处换代 - code-conventions「实现批收尾双登记」改为单登记;CLAUDE.md 目录节、规范导航行、worktree 豁免 行三处换代,红线新增「仓库根禁止设会话状态文件」一条 - roadmap.md 顶部新增「当前位」三行(阶段/迭代位/下一步)接替原快照职责,头注、执行纪律第 3 条、 loop 规范第 8 条、维护纪律四处改指 06 与本文;reports/README.md 与 sim-data/README.md 两处 现行指路改口;architecture.md 文档域闸表行去 active.md 体量闸与触发路径 - 06-待办清单迁入七条真残值(原仅载于该文件):卡片入库纪律悬空待办、req-card 两副本取齐、 魔法道具与罕见残留(实数 23/17 处,旧记约 30/18)、通关口径统一(gdd 内 188 处,旧记 273)、 黑话第二波待发令、数据整改批九条存疑待抽查(该批未提交面所载)、发布前删除 main.gd:196 调试 入口写死行(工程直入·待写卡) harness 侧另批处理(.zcode/ 与用户级技能不入 git):session-snapshot.sh 与 config.json 注册、 worktree-guard.sh 的 active.md 豁免白名单、active-closing 技能、doc-consistency-check 第 8/9 项、 iter 与 req-card 技能里的「唯一例外=active.md」与查尾号条款。
9.1 KiB
代码规范(Dungeon Sweeper)
约束范围:
game/代码同尺度;与 CLAUDE.md「硬性红线」节硬约束(数值表单点 / RNG 封闭流 / Core 零 UI / fail-fast / spec-AC 一致性)并行生效,冲突以用户裁决为准。 分工:本文管结构 / 契约 / 语言 / 数值 / 流程五类;测试的编写与验收见design/dev/test-conventions.md;真实反例库见同目录code-conventions-cases.md(不常驻加载,对规则适用有疑义时查)。
写任何代码前必须通读本文件。
1. 结构纪律——高内聚、低耦合
1.1 禁止上帝对象
一个类只承载一个职责。场景主脚本(main)= 组合根:模式流转、信号接线、核心写调用的唯一出口;渲染、文案拼装、状态装配一律拆分为独立视图/装配器类。单文件超过 ~400 行即触发审视。
1.2 一切功能以类封装,禁止裸函数堆
设计稿与实现同尺度:功能 = 类(状态 + 行为 + 信号),类是封装的最小交付单位。工具性纯函数只允许挂在明确的宿主类下(静态装配器/工厂),不允许无主散落。
1.3 依赖单向,核心写调用完成
依赖方向唯一:views →(信号)→ 组合根 →(写调用)→ core。视图零核心写调用(纯 setter / 信号外发优先);"读核心状态 → 拼展示文案"集中于装配器(presenter);核心写接口(settle_batch / submit_window_selection / runner 推进)只允许在组合根出现。
1.4 命名 = 领域命名,禁止系统 ID 前缀
文件名与类名禁止 a1_/b1_/c1_ 等系统 ID 前缀(a1_board_generator.gd → board_generator.gd)。设计追溯不靠前缀:代码↔设计的追溯由 GDD 文档与 registry 侧承担,系统 ID 只作为文档与 registry 的追溯锚;文件头注不承担追溯职责,不写任何文档链接(§1.4.1)。豁免:D2 schema 类与 autoload;文档/夹具登记名(如 b4_golden)属文档层。
1.4.1 文件头 = ## 文档注释,介绍本模块,≤8 行,两类白名单制
头注的存在性与内容范围以 Python 规范为权威(GDScript 语法近 Python,官方风格指南对文件头零条款,不自造标准):Google Python Style Guide §3.8.2 明文要求——"Files should start with a docstring describing the contents and usage of the module"(文件应以描述模块内容与用法的 docstring 开头);PEP 257——模块一般都应有 docstring,摘要压一行。
载体与上限:只用 ## 文档注释(Godot 官方载体,进编辑器 F1 帮助),总行数 ≤8(不含空行,从文件首个非空行到首个非注释代码行)。
白名单(只许两类):①职责摘要——这是什么,一句话;项目语境(垂直切片状态/验证目标)以括号并入本行。②使用约束——使用本文件前必须知道的禁令与边界,每条一行。
黑名单(出现即违规):日期与变更叙事——改动史查 git log/git blame,变更背景读迭代实现报告;与其他文档或其他文件头重复的内容——零新信息不写(pyguide §3.8.2.1);场景结构、生命周期等代码机制描述——"Never describe the code"(pyguide §3.8.5);一切文档反向链接——「实现 GDD:xxx」「指路:架构见 xxx」一类全部废止,代码↔设计追溯由 GDD 文档与 registry 侧承担。
机器闸:tools/audit_file_headers.py(static_scan S10:行数上限+黑名单机械可判子集)。存量头注按白名单清偿(约 90 文件,清偿批进行中);清偿落地后闸增补「头注必须 ## 开头」锁死载体;此间新增/改动的文件头必须即合规。
1.5 禁止事实约定
任何"大家默认这么做"的惯例必须成文进本文件(或 CLAUDE.md)才算存在。写代码时发现未成文但必须遵守的约定 → 当场补条文,不许靠惯性延续。
2. 契约纪律——跨层/跨类调用的语义
2.1 信号与事件契约成文
每个跨类信号:参数语义、发送时点、消费方依赖,必须在发送方 ## 文档注释成文,每信号一行;计入 §1.4.1 的 8 行上限,装不下时迁契约文档。状态机的每次迁移路径都必须发出对应事件——缺一条路径的事件 = 消费方永久等待 = 软锁。
2.2 跨层标识符语义单一且成文
位置(index)/ 句柄(handle)/ 键(key)是三种不同的东西。跨类传递标识符时,传递方的语义必须与接收方契约逐字一致,禁止凭"当前恰好相等"传值。
2.3 模态覆盖层层级规则
覆盖层遮挡关系由场景树加入顺序决定。打开任何模态覆盖层时,必须显式隐藏会遮挡它的全屏层;新增覆盖层必须登记其在 z 序中的位置,并提供"打开可见性"的场景断言。
2.4 状态字段语义显式
跨战斗/跨场景携带或恢复的状态字段,其语义来源必须显式(表值 / 明确入参),禁止用入参隐式定义。
3. 测试纪律
已独立成文:design/dev/test-conventions.md(探针标配 / 回归断言 / 提交前全量验证 / 验收清单落码规范 / 变异验证)。
4. 语言纪律——GDScript 4.x 实战坑(本项目踩实)
- 多行 lambda 内禁止嵌套 match / 复杂控制流(解析不可靠)——信号处理体一律抽成命名方法 +
bind传状态。 - Dictionary 取值返回 Variant,无类型推断——参与算术或传参前显式声明类型(
var x: float = ...)。 - RichTextLabel:
append_text()不回写text属性——读可见文本用get_parsed_text()。 - lambda 捕获循环变量按创建时值——循环内先落地局部变量再捕获,或用
bind。 - 重命名脚本必须同步
.uid文件;新增class_name后必须跑一次编辑器扫描刷新全局类缓存,否则--headless --script模式解析失败。 print格式占位符与实参类型必须匹配(%d配 String = 静默输出字面量)。- 语言纪律已机器化为 S9 类型闸(迭代 27——2026-10-17 用户裁写入)——
tools/audit_type_hints.py,执行载体=静态扫描域 S9(game/tests/static_scan.sh),退出码 0=归零。扫描面=产品码(game/core+game/data+game/presentation;smoke/tests 豁免——测量面容器直构是既有惯例)。三规则:R1 无类型容器(显式非参数化Dictionary/Array注解)/R2 有值返回缺返回类型(纯副作用缺-> void属写法面不入闸)/R3 参数缺类型(_init豁免——构造注入面形态自由)。 := {}推断形态不算债——var x := {}类赋值推断属类型推断合法面,不入 R1 扫描;只有显式写的非参数化容器注解才算无类型容器。- 行级白名单通道
# type-hint: ignore——豁免该行不入 S9;豁免理由必须随行注明(现行例:board_generator四函数的 db 参鸭子型——typed 参拒冒烟夹具_BoardRowStub注入)。 # rng-seed-exempt标记豁免通道——S1/S2 随机函数扫描对该行豁免;限定用途=非玩法 RNG 消费面的引擎熵(现行例:组合根种子编辑框空态取randi()——建种子不进玩法封闭流)。--script模式禁裸 autoload 标识符——ConfigDB/RngService等 autoload 名在--headless --script模式编译器不解析(parse error);产品码与测试夹具一律经节点路径取用(get_node("/root/…")/AUTOLOAD_PATH_*常量);静态扫描域 S5 硬失败承载在位。- Variant 参数化现行口径——账本类字典/数组标注
Dictionary[Variant, Variant]/Array[Variant]即合格(满足 R1);元素类型精化列后续事项、不入硬纪律,口径变更须用户裁决后续批次另行写入。
5. 数值与汇报纪律
5.1 数值口径必须显式标注尺度
任何期望值/均值汇报必须写明口径:每格 / 每板 / 每战 / 每关。混用口径 = 误导。
5.2 调参先测量,改后复测
改任何玩法数值前,先用扫描工具产出基线(通关率/难度类读数走 balance_verifier.py 冒险段,机制类读数走 reward_expectation.gd 等);改完必须复测回填数据。禁止拍脑袋调参。
5.3 数值设计必须跨尺度推演
在单一尺度校准的数值,必须推演其在更大尺度的复合结果(每战合理 × 关内囤积 = 关卡灾难;反例见 code-conventions-cases.md §5.3)。
5.4 用户拍板的实现零发挥
拍板范围外的细节一律不自行补全——以"待办问题"清单列出等裁决。
6. 流程纪律
- 大改动三段走:设计稿/伪代码 → 用户审阅 → 实现;实现禁止先于审阅。修改记录落切片 README。
- 实现批完成后的登记义务:切片 README 写修改记录,06 条目按 doc-conventions §12.1 推进状态,批次过程与结论进 git 提交信息与
reports/(2026-10-18 用户裁:根目录会话状态文件已废除,禁止再在其中登记条目)。 - 呈现层缺陷的教训回写 D1 GDD 设计输入(信号载荷 schema / 场景级测试 / 时点状态可见性)。