chore(迭代35卡①): 独立验收审计结论入档并按缺漏项收口——删零调用方调试面 generate_for_debug(代拍板第2条撤销)、断言计数改实测 17/39/16=72、config_db 行号订正 :43/:253、闸读数与审计结论补齐、:404/:412 同类掩蔽源标注为已知拦截边界(专指性由 m5/m9b 注入红证补)

This commit is contained in:
DKChan committed 2026-10-24 07:00:16 +08:00
1 parent 6074b3c3c7
commit 90fd434a3c
4 files changed
+143 -13

No files matched your search

-8
View File
@@ -53,14 +53,6 @@ func generate(params: Dictionary, seed_val: int) -> Dictionary:
return built
## 调试面(卡① §8 测试方式两分法——能力验证可经调试接口直改参数档/种子驱动生成图):
## 只构型、不自证不致命,供断言逐条读产出规格违例;生产路径仍走 generate(不合格即致命中止)。
func generate_for_debug(params: Dictionary, seed_val: int) -> Dictionary:
if _rng_service == null:
return {}
return _setup_and_build(params, seed_val)
func _setup_and_build(params: Dictionary, seed_val: int) -> Dictionary:
_params = params
var rg: RandomNumberGenerator = _rng_service.pure_stream(seed_val, SCOPE_STRUCTURE)
@@ -16,7 +16,7 @@
## 白名单外、本批自认为需要呈报的两件
1. **致命面形态修正**:卡片 §7 写「push_error+assert/既有 fatal 路径」。实测 assert 在 headless `--script` 下只中断当前调用链、`OS.crash` 会阻塞跑批且无法被断言消费——故按仓库既有体例(`config_db.gd:78-88` Core 置 `_fatal_flag`+push_error,退出决策归组合根 `main.gd:396 _fatal_screen`)实现:`generate` 不合格时置致命封印+断言+**零交付**(不返回任何图),消费侧(卡② 起关路径)按 `is_fatal()` 停机。契约 4 语义(无兜底图、无软回退、不合格不进玩法)不变,只是停机点从生成器内移到组合根。
2. **调试面新增一件方法**:`generate_for_debug(params, seed)`——只构型、不自证不致命,供断言逐条读产出规格违例(卡片 §8「测试方式两分法」授权经调试接口直改参数档/种子驱动生成图)。生产路径仍只走 `generate`。
2. **调试面曾加一件方法 `generate_for_debug(params, seed)`**——独立验收审计判定其零调用方=死代码,**本批已删除**(断言读产出规格违例改走公有 `validate_output(graph, params)` 直调,能力验证面仍由卡片 §8 两分法的现役 DebugOverlay/DS_DEBUG 承载)。此条不再请求追认,仅作处置留痕。
## 遗留读数义务(实现报告同步在册)
@@ -13,7 +13,7 @@
| T0 事实坐实与跨卡接口对齐 | 完成(卡② 侧对齐随停工移交) | §3 F1–F8 行号与 §2 取用条款抽查:六处关键锚点实查命中(`level_runner.gd:513-525` enc 组装、`enemy_table.gd:157-161` band_of、`config_db_cross_validator.gd:100-106` 迭代 34 检查、`node_map_templates_test.gd:32-104` 宿主、`rng_service.gd:34/:86` 双面、`run_all.gd` manifest 体例)——零漂移;接口定稿见 §三 注 1;RNG 纯流面与支路口径定稿见 `reports/iter35-卡①-代拍板-2026-10-24.md` ①② |
| T1 参数档数据表 | 完成 | `game/data/schemas/level_gen_params.gd`(LevelGenParams,ROW_KEYS 十二键闭集+validate 域校验+row_by_level_index)、`game/data/tables/level_gen_params.tres`(三行 provisional,照卡片 §8.1 逐行填)、`game/core/config_db.gd`(注册+成员+装载+访问器 `level_gen_params_row()`)、manifest 登记一行 |
| T2 生成器核心 | 完成 | `game/core/rng_service.gd` 新增 `pure_stream(seed_val, scope)`(纯派生、不推 `_counter`、不落事件日志);`game/core/node_map_generator.gd`=`generate(params, seed)` 产图+`validate_output(graph, params)` 产出自证+`check_params` 可行性判定+`is_fatal()` 致命封印读面 |
| T3 验收断言批总装 | 完成 | 三宿主共 70 条断言:`level_gen_params_test.gd`〔fv2〕17 条、`node_map_generator_test.gd`〔fv1/fv3/fv5/fv6/fv7/fv9/fv10〕42 条、`node_map_growth_test.gd`〔fv4/fv8〕16 条;manifest 三行全登记(闸 02 实跑套件数 +3) |
| T3 验收断言批总装 | 完成 | 三宿主共 72 条断言:`level_gen_params_test.gd`〔fv2〕17 条、`node_map_generator_test.gd`〔fv1/fv3/fv5/fv6/fv7/fv9/fv10〕39 条、`node_map_growth_test.gd`〔fv4/fv8〕16 条;manifest 三行全登记(闸 02 实跑 58 套件全绿,本批 +3) |
| T4 产出物落位 | 完成(实现报告=本文件;代拍板单、反哺点清单、卡② 停工呈报同批) | `reports/iter35-卡①-实现报告-2026-10-24.md`、`reports/iter35-卡①-代拍板-2026-10-24.md`、`reports/iter35-卡①-反哺点-2026-10-24.md`、`reports/iter35-卡2-停机呈报-2026-10-24.md` |
## 二、完成定义逐条对账(卡片 §1)
@@ -36,7 +36,7 @@
| 尾缀 | 需求点 | 改动落点 | 验收测试(文件:行) | 真实入口 | 撤销/变异证明 |
|---|---|---|---|---|---|
| fv1 | 产出合格+产出自证 | `game/core/node_map_generator.gd` `validate_output()`、`_build()` | `node_map_generator_test.gd:88-89`、`:328-377`(正负向夹具) | `generate(params, seed)` 产前强制+`validate_output(graph, params)` 直调 | m4 首写深度→`:361` 红;m5 注掉终点恒 Boss→`:350` 红;夹具级:dup/dangling/enum/回边/合流各命中对应类别 |
| fv2 | 参数档 schema+.tres+ConfigDB | `level_gen_params.gd`、`level_gen_params.tres`、`config_db.gd:22/:42/:146/:250` | `level_gen_params_test.gd:16,47,50,55,59`+域负向 `:66-101` | `LevelGenParams.validate()`/`ConfigDB.level_gen_params_row()` | m1 L1 出口改 2→`:16` 红;m2 配比合计 0.5→`:16` 红 |
| fv2 | 参数档 schema+.tres+ConfigDB | `level_gen_params.gd`、`level_gen_params.tres`、`config_db.gd:22/:43/:146/:253` | `level_gen_params_test.gd:16,47,50,55,59`+域负向 `:66-101` | `LevelGenParams.validate()`/`ConfigDB.level_gen_params_row()` | m1 L1 出口改 2→`:16` 红;m2 配比合计 0.5→`:16` 红 |
| fv3 | 可复现(纯函数+counter 无关) | `node_map_generator.gd` `generate/_setup_and_build`、`rng_service.gd` `pure_stream` | `node_map_generator_test.gd:99,109,119` | `generate(params, seed)` 同种子两次直调+跨号位双实例对拍 | m3 取数改 `open_stream("node_map")`→`:109` 红 |
| fv4 | 执行边界(无兜底图/fail-fast) | `node_map_generator.gd` `check_params()`+`_fatal()`+`is_fatal()` | `node_map_growth_test.gd:64,70,74,91` | 无解参数档调 `generate`;子进程 `-- fatal-fixture` 真实停机通道 | m11 致命短路改 `pass`→`:91` 红(停机码不再是 1) |
| fv5 | 岔路取舍两条 | `node_map_generator.gd` `_check_fork_rules()`、`_add_forks()` 双禁相邻扩岔 | `node_map_generator_test.gd:163-164`、`:412` | 产图岔口扫描+同类型下一跳夹具 | m8 侧支类型写死 battle→套件经致命通道转红(`:412` 夹具级判据直证下一跳互异) |
@@ -71,11 +71,19 @@
## 五、批末重闸读数
〔闸读数待补——`tools/run_all_gates.sh --code` 回执与逐闸况〕
- 首轮 `tools/run_all_gates.sh --code`(回执 commit `ba660446`):**09 静态扫描 基线绿 → 现红**——新增两类本批违例:S5 core 裸引用 autoload 点标识符 1 处(注释形态)、类型闸 R1 无类型容器 17 处(全在本批新文件)。
- 修复=`c0059bc5`(容器声明补参数化或改推断形;注释去 autoload 点引用形态),单件复跑 `bash game/tests/static_scan.sh` → S1–S12 全 ok、`tools/audit_type_hints.py` → PASS 归零。
- 二轮全量代码域闸(回执 commit `c0059bc5`):**「验收通过——闸况与基线一致,无新增红」**,退出码 0;未跑面=11 回放确定性对拍(本批 diff 触及 RNG/数据表面,对拍须用户批准发起,列存量红·对基线零新增)。00 冒烟/01 系统测试/02 单元与集成(58 套件,含本批新登记三件)/03 探针 --click/04 探针 --full/05 渲染闸/10 熵增闸均与基线一致。
- 死代码清理(审计缺漏⑤)后的三套件与静态扫描复跑读数见 §六末。
## 六、独立验收审计结论
〔待补——审计件 `reports/iter35-卡①-验收审计-2026-10-24.md`〕
审计件:`reports/iter35-卡①-验收审计-2026-10-24.md`(未参与实现的 loop 内子代理,只读卡+对照表+diff+测试,自跑窄测复现撤销证明,不采信本报告自述)。
- **结论=有条件通过**,无必须退回的不通过项:对照表 fv1–fv11 逐行核过,断言真实存在且尾缀可 grep;真实入口未绕过改动点(`generate(params, seed)` 不收关卡号、`validate_output` 在产图主路径被产前强制调用、`pure_stream` 为生成器唯一取数源,生成器内零 `randomize()`/零自建 RNG/零 `open_stream`);diff 零删除、未触 `design/` 与根规则文件;`level_gen_params.tres` 与卡片 §8.1 逐格对上;manifest 三行 `expect: 0` 齐;本报告对 m6–m10 的 NOT-RED 与红点漂移属**如实呈报**(未写成已拦截)。
- 审计独立复现的撤销证明两条:m11(`_fatal(...)` → `pass`)→ 唯一红 `node_map_growth_test.gd:91`〔fv4〕(子进程停机码 1→2),还原后 16 checks 全绿;m4(最长路计算改首写)→ 唯一红 `node_map_generator_test.gd:361`〔fv1〕合法合流图自证,还原后 39 checks 全绿。
- 缺漏五项处置:①断言计数(报告原写 42/合计 70,实测 39/72)→ 已改 §一 T3;②fv2 行 ConfigDB 行号漂移(:42/:250 → 实测 :43/:253)→ 已改 §三;③§五闸读数、§六审计结论原为「待补」→ 本节与上节补齐;④`:404`/`:412` 两条夹具断言按错误**类别**判定,存在同类掩蔽源(同类别的另一判据可顶掉专指性)→ 记为已知拦截边界,判据专指性由 m5/m9b 两条「注掉判据即红」的注入补足(已 RED-OK);⑤`generate_for_debug` 零调用方=本批引入的死代码 → 已删除(生产路径只留 `generate`;断言读产出规格违例改走 `validate_output` 公有面直调),代拍板单第 2 条随之撤销。
- 清理后复跑读数(死代码删除同批):`level_gen_params_test` all green (17 checks)、`node_map_generator_test` all green (39 checks)、`node_map_growth_test` all green (16 checks),退出码均 0;`bash game/tests/static_scan.sh` → S1/S2/S3/S4/S5/S9/S10/S11/S12 全 ok。
## 七、实机目检总清单(登记不阻塞)
@@ -0,0 +1,130 @@
# 迭代 35 卡① 验收审计报告(节点图生成器核心批·合并前独立审计)
- 日期:2026-10-24
- 审计方:独立会话(未参与本批实现)
- 被审工作区:`D:/code/g-plan2-iter35`(分支 `iter35`,HEAD = `6074b3c3`,审读开始前 `git status --short` 为空)
- 基线:`2931b1f2`(开工时 master)
- 依据合同:`reports/需求卡片-节点图生成器核心批-2026-10-21.md` v1.1(§1 完成定义/§4 契约 1–7/§7 任务卡 T0–T4/§8.1 参数档取值表/§8.2 改动—验收对照表/§10 代拍板白名单)
## 一、审计范围与读数依据
### 1.1 实际读过的文件
| 类别 | 文件 |
|---|---|
| 输入合同 | `reports/需求卡片-节点图生成器核心批-2026-10-21.md`(全文 269 行) |
| 被审产出物 | `reports/iter35-卡①-实现报告-2026-10-24.md`、`reports/iter35-卡①-代拍板-2026-10-24.md`、`reports/iter35-卡①-反哺点-2026-10-24.md` |
| 实现本体 | `game/core/node_map_generator.gd`(547 行全文)、`game/core/rng_service.gd`(151 行全文)、`game/core/config_db.gd`(本批 diff 段)、`game/data/schemas/level_gen_params.gd`(81 行全文)、`game/data/tables/level_gen_params.tres`(49 行全文) |
| 断言面 | `game/tests/unit/core/node_map_generator_test.gd`(445 行全文)、`game/tests/unit/core/node_map_growth_test.gd`(115 行全文)、`game/tests/unit/data_config/level_gen_params_test.gd`(106 行全文)、`game/tests/run_all.gd`(diff 段)、`game/tests/unit/test_kit.gd`(协议语义:check/finish/退出码) |
| 闸回执 | `game/tests/.gates/receipt.json`(实现会话批末代码域闸产物,本审计未重跑全量闸) |
| 规则源 | 根 `agents.md`(红线)、`tools/run_all_gates.sh`(09 静态扫描=`game/tests/static_scan.sh`) |
### 1.2 实际跑过的命令与读数
| # | 命令(均在 `D:/code/g-plan2-iter35` 内执行) | 读数 |
|---|---|---|
| R1 | `git log --oneline -5` / `git status --short` / `git branch --show-current` | HEAD `6074b3c3`、分支 `iter35`、工作区干净 |
| R2 | `git diff --stat 2931b1f2..HEAD -- .` 与 `git diff --name-only 2931b1f2..HEAD -- . ':!game'` | `game/` 内 14 个文件、共 1562 行插入;`game/` 之外只有 `reports/` 四份产出物。**零文件触及 `design/`、`AGENTS.md`、`roadmap.md`、`待办清单.md`、`体验验证清单.md`**(`grep -Ei "design/\|AGENTS\|roadmap\|待办\|体验"` 命中 NONE) |
| R3 | `git diff --numstat 2931b1f2..HEAD -- game/` | 14 行删除列全为 `0`——本批对既有代码与既有断言**零删除、零改写** |
| R4 | 套件基线跑(逐条串行,每次先 `taskkill //IM Godot_v4.7.2-stable_win64.exe //F`):`--script res://tests/unit/data_config/level_gen_params_test.gd` | 退出码 0,`all green (17 checks)` |
| R5 | `--script res://tests/unit/core/node_map_generator_test.gd` | 退出码 0,`all green (39 checks)` |
| R6 | `--script res://tests/unit/core/node_map_growth_test.gd` | 退出码 0,`all green (16 checks)`,`[fv4] 无解子进程退出码 = 1` |
| R7 | m11 注入复现(见 §二) | 退出码 1,唯一红点 = `〔fv4〕` 组合根停机码断言 |
| R8 | m11 还原复跑 | 退出码 0,`all green (16 checks)` |
| R9 | m4 注入复现(见 §二) | 退出码 1,`[node_map_generator_test] 1/39 项失败`,唯一红点 = `〔fv1〕` 合法合流图断言 |
| R10 | m4 还原复跑 | 退出码 0,`all green (39 checks)`,工作区回到干净 |
| R11 | 件核 grep:`grep -n "randomize(\|RandomNumberGenerator.new(\|open_stream(\|FileAccess" game/core/node_map_generator.gd` | **零命中**(连注释都没有取数面引用);`grep -n level_index` 只命中第 33 行注释「不收 level_index」 |
| R12 | 件核 grep:全仓 `\.generate(` 非测试调用点 | 只命中 `board_generator.generate(...)`(另一类);`NodeMapGenerator` 的引用面 = 自身+`run_all.gd` manifest+两套新测试,**零生产消费方**(本批不接运行时,与卡片 §5 一致) |
### 1.3 批末代码域闸回执读数(未重跑,只核读)
`game/tests/.gates/receipt.json`:`commit = c0059bc5`、`domain = code`、`all_green = true`、`changed_vs_baseline = []`、`inherited_red = []`;闸 00/01/02/03/04/05/09/10 全 exit 0,闸 11(回放确定性对拍)= `NEED-APPROVAL` 未跑,计入 `not_run`——与「档位须用户发起」红线一致,不算新增红。**注意:实现报告 §五「批末重闸读数」仍是「待补」占位,回执读数没有回填进报告(见 §四 缺漏 3)。**
## 二、A 表:改动—验收对照表逐行核对(实现报告 §三 fv1–fv11)
每行三问:① 断言在测试文件里真实存在(file:line 已 grep);② 「真实入口」列确实走到被改代码;③ 「撤销或变异证明」在报告 §四 有对应注入记录。
| 尾缀 | ① 断言真实存在 | ② 真实入口核实 | ③ 变异记录对应 | 判定 |
|---|---|---|---|---|
| **fv1** 产出合格+产出自证 | 存在:`node_map_generator_test.gd:88,89`(三档×20 种子自证+入口/终点计数)、`:328,332,336,350,361,370,377`(违规夹具与合流夹具) | `generate()` 在 `node_map_generator.gd:47` 无条件调用 `validate_output(built, params)`,不过即 `_fatal` 且零交付(`:48-52`)——**产前强制成立,不是只在测试里直调**;`:82-83` 走 `_graph()`(真 `generate`)产图后再直调一次自证做二次核对 | m4(首写深度)→ 报告记 `:361` 红、m5(注掉终点恒 Boss 判据)→ 记 `:350` 红;**m4 本审计已实跑复现,红点逐字命中 `:361`** | **通过** |
| **fv2** 参数档 schema+.tres+ConfigDB | 存在 17 条:`level_gen_params_test.gd:16,47,50,52,55,62,72,75,78,81,85,88,92,97,100,102,105` | `:16` 走 `db.load_tables("res://data/tables", true)`=生产装载真入口;访问器 `config_db.gd:253 level_gen_params_row()` 实存并被 `:47/50/52` 与测试侧 `_params()`(`node_map_generator_test.gd:38`)消费;schema 直调 `validate()` 是卡片 §8.2 自身指定的入口(数据层无更上层入口),非降级 | m1/m2 → 报告记 `:16` 红 | **通过**(报告 §三 行的落点行号 `config_db.gd:42/:250` 与 HEAD 实值 `:43/:253` 漂移,`/22/146` 正确——见 §四 缺漏 2) |
| **fv3** 可复现(纯函数+counter 无关) | 存在:`:99`(同种子两次逐位同图)、`:109`(跨号位双实例对拍)、`:119`(异种子异图,10 种子去重 ≥8) | 三条全部经 `_graph()`→`NodeMapGenerator.generate(params, seed)`;`:101-111` 用两台服务处不同号位(`new_adventure(1)` vs `new_adventure(999999)`+7 次 `open_stream`)各建新生成器对拍——counter 无关确实从生产产图面进入 | m3(取数改 `open_stream("node_map")`)→ 报告记 `:109` 红 | **通过** |
| **fv4** 执行边界(无兜底图/fail-fast) | 存在:`node_map_growth_test.gd:64,70,74,82,91` | 静态面 `:64/70/74` 直调 `NodeMapGenerator.check_params()`;`:79-91` 用 `OS.execute` 起真实子进程跑 `-- fatal-fixture`,夹具 `_trigger_fatal` 经 `gen.generate(unsolvable, 42)` 真入口产图,再由 `is_fatal()` 决定停机码——审计实跑读数 `[fv4] 无解子进程退出码 = 1`,通道真实 | m11(`_fatal(...)`→`pass`)→ 报告记 `:91` 红;**本审计已实跑复现** | **通过** |
| **fv5** 岔路取舍两条 | 存在:`:163`(下一跳类型互异)、`:164`(支路构成互异+各有独有类型)、`:412`(同类型下一跳夹具)、`:162`(每档每种子的岔口存在性静默条) | `:127-161` 对 `generate` 产图逐岔口独立重算(不复用 `validate_output` 的实现),夹具面 `:412` 直调 `validate_output`;测试侧 `_branch_types()`(`:168-194`)与实现 `_check_fork_rules` 的独占段口径一致(代拍板 ②) | m8(侧支类型写死 battle)→ 报告如实记「进程红、红点落空图致命通道,判据本体由 `:412` 夹具级直证」 | **通过**(判别力短板见 §四 缺漏 4) |
| **fv6** 恰一店+归属锁定+多终点深度互异 | 存在:`:228`(DFS 全路径枚举恰一店)、`:229`(每终点前一位恰一店+店数=终点数)、`:230`(多终点异深)、夹具 `:387,397,404` | 三条主断言走 `generate` 产图+测试自身 `_all_paths()` 枚举(独立实现,非套用被测函数);`:213-221` 另在测试侧重算店数与前驱类型 | m6(商店位改 rest)、m7(两终点同深)→ 报告如实记「进程红,红点落空图致命通道」,未写成 fv6 尾缀专红 | **通过**(判别力短板见 §四 缺漏 4) |
| **fv7** 战斗保底 | 存在:`node_map_generator_test.gd:257`(三档×10 种子计数)、`:343`(低保底合法形状夹具必拒)、`:345`(保底 1 下不误伤) | `:255` 经 `_graph()` 真入口产图计数;`:343/345` 是 `ba660446` 专门为「让判据可被变异拦下」补的正反夹具,一拒一不误伤,判据按消息文本「低于保底」专断 | m9(砍穿保底)报告如实记「红点未落〔fv7〕尾缀、中止于空图读面」,并以 **m9b**(注掉判据)作判据级 RED-OK 记 `:343` 红 | **通过** |
| **fv8** 生长递增 | 存在:`node_map_growth_test.gd:57`(步数逐关变大)、`:58`(节点总数递增且增幅变大)+`:43-52` 五种子静默逐档读数 | `_reading()`(`:31`)经 `gen.generate(db.level_gen_params_row(L), 42)` 真入口,参数档从生产表读回,非硬编码 | **m10 = NOT-RED**,报告在 §三 与 §四 两处均明写「NOT-RED/如实标注拦截边界」,未冒充已拦截 | **通过**(拦截边界已如实呈报,见 §四 缺漏 5) |
| **fv9** 含岔口与出口结构 | 存在:`node_map_generator_test.gd:285`(三档各含 ≥1 岔口)、`:286`(L1 终点恰 1)、`:287`(L2/L3 含分区域大岔口) | 全走 `generate` 产图结构扫描+测试自身 BFS `_terminals_reachable()` | m12(`wanted` 写死 0)→ 记 `:285` 红 | **通过** |
| **fv10** RNG 单点(纯流面) | 存在:`node_map_generator_test.gd:313`(产图前后 counter 同值)、`:316`(同 (seed,scope) 同流)、`:317`(不推计数器且产图非空) | `:308-318` 真实例化 `RngServiceCore` 注入生成器、走 `generate` 产图后读 `counter()`;`pure_stream` 直调亦存在。静态面:R11 grep 在 `node_map_generator.gd` 内零命中 `randomize(`/`RandomNumberGenerator.new(`/`open_stream(`,生成器唯一取数点为 `:66 _rng_service.pure_stream(seed_val, SCOPE_STRUCTURE)`;闸 09 静态扫描回执 exit 0 | 与 m3 同发注入(报告记 `:109` 红) | **通过** |
| **fv11** 反哺点清单(非行为改动) | 件核对象存在:`reports/iter35-卡①-反哺点-2026-10-24.md` 七条表行 | 卡片 §6 六条逐格对上:①生成规格(多终点异深+最长路径赋值)②地图 :65 消歧③冒险结构 :293 深度域登记④level-map 呈现随动⑤待办清单 06 状态⑥roadmap 编入笔;另加实现新发现⑦(出口数 3 是支路互异天花板)。每条有「文件与节/改成什么/依据」三列 | 纯文档产出物,无代码变异,报告与卡片均标「非行为改动」 | **通过** |
**契约逐条复核(与 A 表交叉)**:契约 1(纯函数+counter 无关+纯流面)=fv3/fv10 过;契约 2(id/depth 拆两轴+最长路径赋值+多终点异深)=节点字段恰 `id/type/depth/next`(`_mk:414`)、`validate_output:174-179` 逐节点比对最长路值、`:219-224` 异深判据,过;**契约 6(`generate` 不收 level_index)**=签名 `generate(params: Dictionary, seed_val: int)`(`:34`),全仓调用点零传关卡号(R12),过;契约 4(无兜底图)=生成器内零模板/零上一张/零空图回退分支,三处 `return {}` 全在 `_fatal` 之后(`:41/45/52`,注释明写「致命中止后不可达;本行即无残图交付的显式证明」),过。
## 三、B 段:撤销证明复现记录(2 条,真跑)
前置:`git status --short` 空;`node_map_generator.gd` 为 UTF-8、547 行全 CRLF(注入后仍 547 CRLF,行尾未被工具改写)。
### B1 · m11 无解路径致命短路
- 锚点注入(`game/core/node_map_generator.gd:40`,唯一命中,1 行改):
- 原文:`_fatal("参数无解致命中止(契约 4——无兜底图、禁软回退)")`
- 注入:`pass # m11 mutation injection`
- 跑:`--script res://tests/unit/core/node_map_growth_test.gd` → **退出码 1**
- 红点读数(逐字):
- `[fv4] 无解子进程退出码 = 2`(原为 1)
- `ERROR: [FAIL] 无解参数档置致命封印并由组合根停机(退出码恰 1,无残图交付)〔fv4〕`
- 同批其余三条〔fv4〕(`:64/70/74`)仍 PASS——红点精确落在子进程停机通道那条,未泛化。
- 还原:`git checkout -- game/core/node_map_generator.gd`(HEAD 已含实现,安全)→ `git status --short` 空
- 还原复跑:**退出码 0,`all green (16 checks)`**
- 结论:**与报告 §四 m11 记录逐字一致,RED-OK 复现成立。**
### B2 · m4 最长路径计算改首写
- 锚点注入(`node_map_generator.gd:440`,唯一命中,1 行改):
- 原文:`out[nid] = maxi(int(out.get(nid, 0)), int(out[id]) + 1)`
- 注入:`if not out.has(nid): out[nid] = int(out[id]) + 1 # m4 mutation injection`
- 跑:`--script res://tests/unit/core/node_map_generator_test.gd` → **退出码 1**
- 红点读数(逐字):`ERROR: [node_map_generator_test] 1/39 项失败`,唯一 FAIL 行 =
- `ERROR: [FAIL] 合法合流图(第二入口直插主链,深度取最长路 3)自证零错误〔fv1〕`
- 首写口径使合流节点取到短路值(3→1),与 `:174-179` 最长路比对不符 → 自证报错,正是报告 §四 m4 声明的红点位置。
- 关键旁证:三档×20 种子主自证〔fv1〕`:88` 仍 PASS(生成器构型无合流,取长/取首等价)——说明这条断言拦的正是「合流图深度语义」,不是泛泛报错。
- 还原:`git checkout -- game/core/node_map_generator.gd` → 工作区干净
- 还原复跑:**退出码 0,`all green (39 checks)`**
- 结论:**与报告 §四 m4 记录逐字一致,RED-OK 复现成立。**
## 四、C 段:测试削弱检查(逐条给依据)
| 检查项 | 结论 | 依据 |
|---|---|---|
| 旧断言删改 | **零削弱** | `git diff --numstat` 14 个文件删除列全为 0;`run_all.gd`+3 行、`config_db.gd`+8 行、`rng_service.gd`+14 行(`pure_stream` 纯新增,`open_stream/derive_at` 未触);三套测试全为新建文件——与卡片 §8.2「零旧断言改写」预声明一致 |
| manifest 登记(未登记=闸 02 不执行) | **齐且口径正确** | `run_all.gd` 三行新增均为 `"expect": 0`,路径与盘上文件一一对应:`tests/unit/data_config/level_gen_params_test.gd`、`tests/unit/core/node_map_generator_test.gd`、`tests/unit/core/node_map_growth_test.gd`;三套件单跑退出码实测均 0(R4/R5/R6),与 expect 0 自洽 |
| 参数档数值 vs 卡片 §8.1 | **逐格对上,无放宽** | `level_gen_params.tres`:layers 6/9/13 ✓、branch_density 0.3/0.5/0.7 ✓、配比 .50/.20/.20/.10|.50/.20/.15/.15|.55/.15/.15/.15(各合计 1)✓、entry 1/2/2 ✓、exit 1/2/3 ✓、battle_floor 4/6/8 ✓、fork 2/3 三档 ✓;代拍板 ④ 自陈「取卡片原值、未做域内微调」与实物一致 |
| 扫描面种子数是否被缩小 | **未见对卡片的缩小;有一处对报告自述的漂移** | 卡片 §8 V1/T3 措辞=「三关参数档×固定种子」,未规定种子条数。实测主自证面 `node_map_generator_test.gd:81 range(42, 62)`=42–61 共 **20 种子 × 3 档**,与报告 §二#1「三档 × 20 种子(42–61)」一致;其余面:fv5/fv6/fv9 各 3 种子〔42,43,44〕、fv7 10 种子、fv8 5 种子、fv3 异图 10 种子——均落在卡片授权面内。**漂移在报告侧**:报告记该套件 42 条、实测 39 条(见缺漏 1) |
| 生成失败的回退分支(契约 4 禁) | **零回退分支** | 生成器不引用 ConfigDB/`level.tres`/模板池(R11/R12 grep 零命中),无「失败用模板/用上一张」路径;`_fatal` 后三个 `return {}` 是停机后的不可达行、并由 `is_fatal()` 要求消费侧拒收;本批**无任何生产调用方**取用产图(`NodeMapGenerator` 引用面=自身+manifest+两测试),故 `{}` 不存在被当合法图消费的现实通道 |
| `--script` 禁裸 autoload(F8/code-conventions:71) | 合规 | 生成器 `_init(rng_service = null)` 构造注入,未注入即 `push_error`+致命(`:42-45`);测试侧 `RngScript.new()` 显式实例化后注入 |
| NOT-RED 与「红点落别处」是否如实呈报 | **如实** | 报告 §四 m10 明写 `**NOT-RED**` 并在 §三 fv8 行再次标注;m6/m7/m8/m9 明写「拦截发生(进程红),红点落在空图致命通道/未落〔fv7〕尾缀」,并各自改以夹具级断言(`:404/:387/:412`)或 m9b 作判据级证明——四条**均未被写成 RED-OK/已拦截**,符合「无变异红记录只写已实现、拦截能力未证」红线 |
| 像素纪律/数值单点 | 合规 | 本批无像素结构件;玩法数值只落 `.tres`,生成器不硬编码旋钮值(全部读 `params`)。实现自由面常量(`MAX_WIDTH=4`、三岔概率 `0.35`、`_trunk_len` 取 `L/2`)属 HOW 面,卡片 §10 ⑤ 授权、报告 §八与代拍板 ⑤ 已登记其副作用(分支密度实际生效数受锚点几何限制) |
### 缺漏与待办(审计判定,非红线违例)
1. **实现报告断言计数不符**:报告 §一 T3 与 §二#7 记 `node_map_generator_test` 42 条、合计 17/42/16;HEAD 实测 **39 条、合计 17/39/16 = 72 条**(另 `63a6ea80` 提交信息记 68 条,说明该数在批内漂移后未回填)。合回前须把报告读数订正为实测值。
2. **实现报告 §三 fv2 行的落点行号漂移**:记 `config_db.gd:22/:42/:146/:250`,HEAD 实值 `:22/:43/:146/:253`。
3. **实现报告 §五(批末重闸读数)与 §六(审计结论)仍为「待补」占位**:完成定义 #8 要求重闸读数入报告;回执已在盘(`c0059bc5`/`domain=code`/`all_green=true`/闸 11 按红线未跑),须把这段读数抄进 §五,本报告可作 §六 依据。
4. **三条夹具级断言按错误类别判定、判别力弱于消息级**:`:404`(终点前驱非店)与 `:412`(岔口同类型下一跳)用 `_has_cat(..., "structural")`——若只注掉该条判据、同夹具另有其它 structural 违例,断言可能仍绿(`:404` 的夹具确实同时触发「店数≠终点数」「穿店数≠1」两类,存在掩蔽源);`:387`(多终点同深)经逐节点推演无同类掩蔽源,专指成立。对照:`:350`(终点非 Boss)与 `:343`(低于保底)已按消息文本专断,是应当效仿的体例。**不阻塞合回**——m5/m9b 已证这两条判据可被拦,m6/m7/m8 已从真实 `generate` 入口证得套件级拦截。
5. **m10 拦截边界真实存在**:「只调分支密度」不足以破坏节点总数增幅递增。报告已把单调性交给参数档域校验(层深递增且增幅变大,`level_gen_params.gd:64-71`+`:85` 断言)与 fv8 三档读数共同承载,属如实标注,不是漏判。
6. **新增旁路入口 `generate_for_debug`(`:58-61`)当前零调用方**:只构型、不自证、不致命。卡片 §8 两分法授权调试接口,但代拍板单把它列为「白名单外需呈报第 2 件」待用户追认;本批无运行时接线故不构成「不合格产出进玩法」通道。卡② 接线时须保持生产路径只走 `generate`。
7. **代拍板六条+白名单外两件待用户追认**(致命面形态从「生成器内停机」改为「置封印+组合根停机」,fv4 判据随之改为「停机码恰 1」)——语义等价、有断言兜住,但追认动作未完成。
## 五、结论
**有条件通过(可以合回,条件是下列三件在合回动作前后立即补齐,无需重跑实现)**:
1. 实现报告 §五 回填批末代码域闸读数(回执 `c0059bc5`:domain=code、all_green=true、闸 11 按红线未跑)、§六 挂本审计报告,并把断言计数由 42 订正为实测 39(合计 72)。
2. 实现报告 §三 fv2 行的 `config_db.gd` 行号按 HEAD 实值订正(`:43/:253`)。
3. 用户对 `reports/iter35-卡①-代拍板-2026-10-24.md` 六条+白名单外两件(致命面形态、`generate_for_debug`)作追认或推翻;推翻则回写实现面。
判定依据:卡片 §1 完成定义八项逐条有真实入口断言兜住(§二 A 表全通过);两条撤销证明(m11/m4)独立复现且红点逐字命中报告声明;本批零删改既有代码与既有断言、零 `design/` 与根规则文件触碰、参数档数值与卡片 §8.1 逐格一致、无回退分支、RNG 单点静态核零命中;NOT-RED 与红点漂移均如实呈报。
**不通过项清单**:无(不存在必须退回实现或上游的缺漏;上述三件为产出物回填与用户裁决动作,非事实性缺陷)。
**另须留意(非本批验收范围)**:卡② 因 §0 硬交付序列的「生成图深度扩面覆盖批」未立卡而停工(`reports/iter35-卡2-停机呈报-2026-10-24.md`),迭代 35 因此不是一次合并——卡① 可否单独合回属用户拆批裁决,本审计只判定卡① 代码面验收闭合。