From 4cec838f0eb8db5ff44dd97c0378f2952f87b8d8 Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Sat, 24 Oct 2026 19:28:06 +0800 Subject: [PATCH] =?UTF-8?q?docs(=E8=BF=AD=E4=BB=A335=E5=8D=A1=E2=91=A1T4?= =?UTF-8?q?=20=E4=BA=A7=E5=87=BA=E7=89=A9):=20=E5=AE=9E=E7=8E=B0=E6=8A=A5?= =?UTF-8?q?=E5=91=8A=E8=A1=A5=20T2=20=E4=BA=8C=E5=8F=A3/T3=20=E5=85=A8?= =?UTF-8?q?=E6=AE=B5=E4=B8=8E=E5=8F=98=E5=BC=82=E9=AA=8C=E8=AF=81=E8=AE=B0?= =?UTF-8?q?=E5=BD=95=E8=A1=A8=E4=B8=83=E6=9D=A1=EF=BC=88M1-M7=20=E6=B3=A8?= =?UTF-8?q?=E5=85=A5=E7=82=B9=E3=80=81=E6=9C=80=E7=AA=84=E5=AE=BF=E4=B8=BB?= =?UTF-8?q?=E3=80=81=E7=BA=A2=E8=A1=8C=E5=8E=9F=E6=96=87=EF=BC=8CV5=20?= =?UTF-8?q?=E4=B8=A4=E6=9D=A1=E7=94=B1=E7=94=9F=E4=BA=A7=E7=A0=81=E6=B3=A8?= =?UTF-8?q?=E5=85=A5=E5=8F=96=E8=AF=81=E5=B9=B6=E5=A3=B0=E6=98=8E=E5=AE=BF?= =?UTF-8?q?=E4=B8=BB=E5=86=85=E8=81=94=E5=8F=98=E5=BC=82=E8=84=9A=E6=89=8B?= =?UTF-8?q?=E6=9E=B6=E5=B7=B2=E6=B8=85=E9=80=80=EF=BC=89=EF=BC=8B=E5=95=86?= =?UTF-8?q?=E5=BA=97=E5=AE=BF=E4=B8=BB=E6=94=B6=E5=8F=A3=E6=AE=B5=EF=BC=88?= =?UTF-8?q?=E6=8D=A2=E4=BB=A3=E5=90=8E=E5=8F=96=E6=95=B0=E5=8D=95=E7=82=B9?= =?UTF-8?q?=E3=80=81S3=20=E4=B8=89=E6=80=A7=E8=B4=A8=E6=89=AB=E6=8F=8F?= =?UTF-8?q?=E9=9D=A2=2060=20=E5=9B=BE/1413=20=E8=B7=AF=E5=BE=84=E8=AF=BB?= =?UTF-8?q?=E6=95=B0=E3=80=81S4/S5=20=E9=9D=9E=E7=A9=BA=E5=89=8D=E7=BD=AE?= =?UTF-8?q?=E6=B8=85=E5=8D=95=EF=BC=89=EF=BC=9B=E6=96=B0=E5=BB=BA=E4=BB=A3?= =?UTF-8?q?=E6=8B=8D=E6=9D=BF=E8=BF=BD=E8=AE=A4=E5=8D=95=EF=BC=88=E7=99=BD?= =?UTF-8?q?=E5=90=8D=E5=8D=95=E5=85=AD=E6=9D=A1=E6=89=A7=E8=A1=8C=E5=80=BC?= =?UTF-8?q?=20graph=5Fgen=5Fv2=20=E5=91=BD=E5=90=8D/=E5=8F=A5=E6=9F=84?= =?UTF-8?q?=E6=96=AD=E7=82=B9=E5=BD=A2=E6=80=81/route=20=E8=BD=B4=E4=B8=8E?= =?UTF-8?q?=20level=5Fmaps=20=E5=80=BC=E5=BD=A2=E6=80=81/=E6=8F=90?= =?UTF-8?q?=E4=BA=A4=E5=88=87=E5=88=86=EF=BC=8B=E8=B6=85=E6=B8=85=E5=8D=95?= =?UTF-8?q?=E4=BA=94=E4=BB=B6=E5=91=88=E6=8A=A5=EF=BC=9A=E5=A5=96=E5=8A=B1?= =?UTF-8?q?=E5=BF=85=E7=BB=8F=E6=96=AD=E8=A8=80=E6=9B=BF=E4=BB=A3=E5=BD=A2?= =?UTF-8?q?=E6=80=81=E3=80=81=E4=B8=89=E5=A4=84=20=5Flevel=5Factive=5Fnode?= =?UTF-8?q?s=20=E7=A9=BA=E6=89=AB=E6=8F=8F=E5=81=87=E7=BB=BF=E6=B8=85?= =?UTF-8?q?=E5=81=BF=E3=80=81=E5=95=86=E5=BA=97=E5=88=B0=E8=BE=BE=E8=AF=BB?= =?UTF-8?q?=E6=95=B0=202=E2=86=923=E3=80=81=5Fboss=5Fdepth=20=E6=AD=BB?= =?UTF-8?q?=E4=BB=B6=E9=9A=8F=E5=88=A0=E3=80=81=E4=B8=A4=E5=91=88=E7=8E=B0?= =?UTF-8?q?=E5=AE=BF=E4=B8=BB=E5=A4=B9=E5=85=B7=E6=8B=93=E6=89=91=E9=87=8D?= =?UTF-8?q?=E5=BB=BA=E5=BE=85=E5=A4=8D=E6=A0=B8=EF=BC=89=EF=BC=9B=E6=96=B0?= =?UTF-8?q?=E5=BB=BA=E5=8F=8D=E5=93=BA=E7=82=B9=E6=B8=85=E5=8D=95=EF=BC=88?= =?UTF-8?q?=E5=8D=A1=E7=89=87=20=C2=A76=20=E5=85=AD=E6=9D=A1=E9=80=90?= =?UTF-8?q?=E8=90=BD=E7=82=B9=EF=BC=8B=E6=96=B0=E5=8F=91=E7=8E=B0=E5=9B=9B?= =?UTF-8?q?=E6=9D=A1=EF=BC=9A=E9=AA=8C=E8=AF=81=E9=9B=86=E6=B8=85=E5=8D=95?= =?UTF-8?q?=2011=20=E8=A1=8C=E9=99=88=E6=97=A7=E4=B8=8D=E5=8F=97=E9=97=B8?= =?UTF-8?q?=E8=A6=86=E7=9B=96=E3=80=81node=5Fmap=5Ftemplates=20=E5=AE=BF?= =?UTF-8?q?=E4=B8=BB=E5=90=8D=E9=81=97=E7=95=99=E3=80=81level.tres=20?= =?UTF-8?q?=E8=A1=A8=E5=B0=BE=E5=8E=BB=E5=90=91=E6=B3=A8=E8=AE=B0=E4=B8=8E?= =?UTF-8?q?=E7=A6=81=E5=86=99=E5=8F=98=E6=9B=B4=E5=8F=99=E4=BA=8B=E7=BA=A2?= =?UTF-8?q?=E7=BA=BF=E5=BC=A0=E5=8A=9B=E3=80=81=E6=95=99=E5=AD=A6=E6=8B=85?= =?UTF-8?q?=E5=AD=90=E4=BA=A4=E6=8E=A5=E9=9C=80=E5=85=A5=E4=BD=93=E9=AA=8C?= =?UTF-8?q?=E9=AA=8C=E8=AF=81=E6=B8=85=E5=8D=95=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- reports/iter35-卡②-代拍板-2026-10-24.md | 29 +++++++++++++ reports/iter35-卡②-反哺点-2026-10-24.md | 25 +++++++++++ reports/iter35-卡②-实现报告-2026-10-24.md | 51 +++++++++++++++++++++++ 3 files changed, 105 insertions(+) create mode 100644 reports/iter35-卡②-代拍板-2026-10-24.md create mode 100644 reports/iter35-卡②-反哺点-2026-10-24.md diff --git a/reports/iter35-卡②-代拍板-2026-10-24.md b/reports/iter35-卡②-代拍板-2026-10-24.md new file mode 100644 index 00000000..999f1036 --- /dev/null +++ b/reports/iter35-卡②-代拍板-2026-10-24.md @@ -0,0 +1,29 @@ +# 迭代 35 卡② 代拍板追认单(节点图消费侧换代批) + +- 日期:2026-10-24 +- 依据:`reports/需求卡片-节点图消费侧换代批-2026-10-21.md` §10 代拍板白名单六条——授权发生在写卡段,本批只执行预授权并留痕 +- 待用户动作:追认或推翻。推翻任一条即回写对应实现面(不改设计文档) + +## 一、白名单内六条的执行值 + +| # | 卡片白名单条目 | 本批拍定值 | 落点 | +|---|---|---|---| +| ① | 图数据内部适配形态 | 生成图落到 `level_row` 的**行副本**上(`row.duplicate(true)` + `merged["nodes"] = graph["nodes"]`),表本体不被写脏;节点字段恰 `id/type/depth/next`,句柄即 `id`;读面 API 六签名逐字不变 | `game/core/level_runner.gd` `_assign_generated_graph`/`nodes()`;断言=`node_map_templates_test` 「起关生效图=生成器同档同种子直取逐位一致」 | +| ② | 校验实现形态与错误类别命名 | 无环判据取「出边目标 `depth` 严格大于源」写法(不做 DFS 判环);错误类别沿用 `structural`/`dangling_next`/`dup_key`/`enum`/`domain` 词表,零新增类别 | `game/data/schemas/level_table.gd` `validate_graph`;断言〔v1〕17 条 | +| ③ | 断点键换代细节 | 代差标记键命名 `graph_gen_v2`(值恒 1);退役键=`template_pick`;`node_id`/`visited_ids` 按图内句柄落档(与 `current_node_id()`/`visited_ids()` 同空间);旧断点拒绝后的盘面处置=**留档不清**(`resume_adventure` 返回 false + push_error,菜单侧「继续上局」自然失效由既有空断点态承载) | `game/core/adventure_runner.gd` `_snapshot_breakpoint`/`resume_adventure`;断言=`breakpoint_resume_test` P7 六条+`node_map_templates_test` ⑤ 拒绝条 | +| ④ | 冒烟断言定位写法与措辞 | 断言定位两分:**结构/覆盖/确定性类**直取生成器(参数档+种子 42/42–61 扫描),**行进/停点/兑付类**走 runner 与 AdventureRunner 真实入口(`start_level`/`start_level_external`/`pick_next_node`/`resume_adventure`);断言文本一律不写死节点编号形状 | `game/tests/integration/node_map_templates_test.gd`、`game/tests/unit/core/level_shop_economy_test.gd`〔v11〕、`game/tests/unit/core/adventure_feats_test.gd` | +| ⑤ | route 轴实现与 MC 字段值形态 | route 轴沿用「候选句柄升序= min/降序= max」的既有评分 tie-break(`_route_pick` 只换寻址空间,评分逻辑零动);MC 出数字段 `level_templates` → `level_maps`,值形态 `"%d#%d" % [关卡序号, 主种子]`(关卡×生成图标识) | `game/sim/level_autoplay.gd` `_route_pick`/`_on_adventure_node_entered`、`game/sim/adventure_monte_carlo.gd` 出数面 | +| ⑥ | 提交切分与分支命名 | 分支 `iter35b`(工作区 `../g-plan2-iter35b`);切分=覆盖数据批 → T1 校验换代 → T2 一口(④静态检查退役+随动)→ T2 二口+T3 断言面主体 → T3 收口(商店宿主)→ 变异验证与产出物 | git log(`9214ef8e`、`c0dd4420`、`98c61d50`、`9ee3bea1` 及后续收口笔) | + +## 二、白名单外、本批自认需要呈报的五件 + +1. **「奖励节点三选一 ≥1 次」断言的替代形态**(`adventure_feats_test`)。旧判据「L1 链必经 1 个」的前提是单链模板形状,随模板池消亡;实测确定性选路评分在种子 42–47 × min/max 两轴共 12 次全程冒险里**一次都没有走进奖励支路**(生成图里奖励节点的句柄序恒在战斗支路之后,评分优先推进)。若保留「≥1 次」原句就是逼着改扫描口径凑数。本批拆成两条:① 图侧「三关生成图各含 ≥1 奖励节点」;② 行进侧走真实入口——打赢入口战、在岔口显式 `pick_next_node` 点奖励支路、断言三选一候选可取(3 件)且停点在途且兑付受理。语义从「形状必经」换成「接线可用+图上存在」,未放宽到恒真。 +2. **三处 `_level_active_nodes` 副本曾是假绿**。`templates` 键清出后该 helper 落到 `row.get("nodes", [])` 返回空数组,凡以它为节点的扫描断言(覆盖义务、Boss 深度、逐节点行集)都变成「扫描面为空所以零违例」的空转绿。本批把三宿主 helper 换成参数档+种子 42 的生成图取数,并在覆盖断言里加「扫描节点数 > 0」的非空前置。这条是缺陷清偿,不是判据改动,但因为它把三条一直绿着的断言重新变成有效的(当场新增暴露一次 `boss_depth` 读到 -1 的真红),特此留痕。 +3. **商店到达余额读数 2 → 3**(`adventure_feats_test` ⑦ GP 跨关延续)。旧断言 `shop_seq.size() == 2` 的依据是「L1 单链无店、L2/L3 各一店」;卡② 商店编排语义为「每终点前恰一店」⇒ 每关路径必穿一店 ⇒ 三关全程 = 3 次到达。本批按新语义把读数断言改成 3 并保留「首达余额 > 0」。若 S3 三性质扫描(`level_shop_economy_test`)与这条投影不一致,二者之一必红,属互相校验。 +4. **`_boss_depth` helper 随删两处**(`round_flow_skill_pool_test`、`table_structure_guard_test`)。它们调用已退役的模板取数面、且在各自宿主内**零调用方**(〔fv13〕换代时留下的死件)。按契约 6「禁留死代码」删除;不涉及任何断言删除。 +5. **两个呈现宿主的夹具拓扑重建**(`level_map_type_vis_test`、`level_map_info_fog_test`)。旧夹具用「6→3 回边」表达非法图,而新形状要求 `depth` 沿出边严格前进,回边无法自洽表达;本批把该夹具改为长跳前向边+侧链节点,保留全部阈值与可见集断言,负向回边判据改由 `level_table_validate_test`〔v1〕的夹具图承载。此条由并行子代理执行,**独立验收审计须复核其「断言条数与阈值零改动」的自述**(自述见实现报告随动段)。 + +## 三、遗留读数义务(与实现报告同册) + +- 用户目检两条未做(登记不阻塞):三关实机选路观感不回归、首局种子 42 固定图的教学体验。 +- MC/对拍零跑:本批无玩法数值改动,按红线不发起跑批;11 回放确定性对拍按前批裁决不补跑。 diff --git a/reports/iter35-卡②-反哺点-2026-10-24.md b/reports/iter35-卡②-反哺点-2026-10-24.md new file mode 100644 index 00000000..c15d278e --- /dev/null +++ b/reports/iter35-卡②-反哺点-2026-10-24.md @@ -0,0 +1,25 @@ +# 迭代 35 卡② 反哺点清单(节点图消费侧换代批) + +- 日期:2026-10-24 +- 依据:`reports/需求卡片-节点图消费侧换代批-2026-10-21.md` §6 关联文档同步面六条+实现批执行中新发现的落点 +- 处置:本批为代码实现批,禁写 `design/` 与根流程清单,以下只列不改;每条由用户裁决后归文档批落文 + +## 一、卡片 §6 预列六条 + +| # | 文件与节位 | 现状陈述 → 应改成 | 依据 | +|---|---|---|---| +| ① | `design/gdd/systems/冒险循环/关卡节点地图.md` :57/:156/:178 | 「战斗|携带节点编号」「组装关卡序号 + 节点编号」「每场开战调用携带(关卡序号 + 节点编号)」三处 → 统一为「关卡序号+节点深度(自入口步数)」,与 :23/:65/:111/:119 同口径 | 卡② 契约 2(弃节点编号寻址)+ D1:65/:119 定稿句;实现落点 `game/core/level_runner.gd` enc 组装段(`node_depth` 取节点 `depth` 值) | +| ② | `design/gdd/systems/冒险循环/冒险结构.md` :293、:264 | :293 覆盖义务「每个战斗与关底节点(关,深)在敌人与棋盘生成的数值表中有精确行」→ 「敌侧按深度带命中(落带不早于请求深度,禁顶 clamp 消解)+板侧解析命中」;:264 关卡行集行的「旧模板池随实现批清数据」括注已成既成事实 → 注销括注、改述为参数档+生成器承载 | 卡③ 契约 1+卡② 完成定义 6;实现落点 `game/data/tables/level.tres`(templates 键已清出)、`game/tests/unit/core/level_shop_economy_test.gd` 覆盖断言〔v11〕 | +| ③ | `design/gdd/systems/冒险循环/关卡节点图生成.md` | 用语核对结论:消费侧注释只引用其「产出规格/执行边界」节号,未发现「岔口/终点/路径」用语漂移 → 记「无漂移」 | 实现在 `game/data/schemas/level_table.gd`、`game/core/level_runner.gd` 注释面自查(卡② T0 事实坐实项) | +| ④ | `design/gdd/ux/level-map.md` | 呈现面随动登记:句柄寻址后地图显示的节点数字=图内句柄 id(非深度、非数组序),多入口/多终点/含岔口三形态需补呈现条款 → 归卡④ 或文档批处理,本批未改呈现代码 | 卡② §6 表「呈现面随动义务」;实现落点 `game/core/level_runner.gd` `node_id_of`/`visited_ids` 语义换代 | +| ⑤ | `待办清单.md`(06) | 卡② 条目状态推进与退役记载:本批实现闭合后该条目按流水线规则由收口段处理,本会话未改该文件 | req-card 06 状态回写义务+迭代批禁改根流程清单红线 | +| ⑥ | `roadmap.md` | 迭代 35 行批内状态刷新(卡② 由「已编」推进到「实现批完成待收口」)——本会话未改该文件 | 同上(实现批禁写根规则文件) | + +## 二、实现批新发现的四条(卡片未预列,一并呈报) + +| # | 文件与节位 | 发现 | 建议处置 | +|---|---|---|---| +| ⑦ | `game/tests/验证集清单.md`(批 B 迁移账本的断言索引,11 行含 `first_script`/`template_pick` 措辞) | 该清单是批 B 迁入时的断言文本快照索引,只由 `tools/extract_checks.py` 手工重生成、不进任何闸;卡② 断言换代后其中 11 行文本与行号已过期 | 由用户裁决:跑一次 `tools/extract_checks.py` 重生成,或在清单头部登记「换代批后快照失效、按宿主现文为准」 | +| ⑧ | `game/tests/integration/node_map_templates_test.gd`(宿主文件名) | 该宿主现承载「生成图确定性断言套」,文件名里的 templates 是模板时代遗留名;卡片 S6 明令换代断言落「S1 同宿主」且 manifest 零新增登记,故本批保留原名 | 待用户裁决:改名(如 `node_map_determinism_test.gd`)须同批改 `run_all.gd` manifest 路径行,属独立小批 | +| ⑨ | `game/data/tables/level.tres` 表尾注释 | 卡片 T3 要求表尾写「15 张模板去向+参数档字段指引」,实现里带了一句「随迭代 35 卡② 清出」的迭代叙事,与 doc-conventions §5「禁写变更叙事」的口径有张力 | 待用户裁决:保留(卡片明令的去向注记)或删去迭代号只留图源换代事实句 | +| ⑩ | `design/gdd/systems/冒险循环/关卡节点地图.md`(或 06 体验验证清单)——教学担子交接 | 卡② 待裁点已定「模板 0 教学重放语义废除,教学位由首局固定种子 42 的生成图承载」;文档侧仍写着「模板 0=教学图」的表述在 ①②之外的段落里残留,且「首局图观感是否可当教学」属真人判断 | 建议随 ①② 一并清扫措辞,并把「首局教学图体验」列进 `体验验证清单.md`(卡片 §8.2 已把它列为用户目检项,登记不阻塞) | diff --git a/reports/iter35-卡②-实现报告-2026-10-24.md b/reports/iter35-卡②-实现报告-2026-10-24.md index 8d12c4ae..bf6d9fa6 100644 --- a/reports/iter35-卡②-实现报告-2026-10-24.md +++ b/reports/iter35-卡②-实现报告-2026-10-24.md @@ -89,6 +89,57 @@ 6. 收口顺序:T2+T3 必须同轮(拆开中间态必红)→ `run_all_gates.sh --code` 全绿 → 独立验收审计 → 合回 → 反哺点/代拍板/待办清单状态随批。 7. 待用户项:覆盖批八行与棋盘 12 行数值为插值 provisional(真人试玩定味);数值面已动,11 回放确定性对拍与 `balance_verifier` 是否发起需重新裁定。 +## 二·九 T2 第二口=消费侧切源主体(已完成·提交 `9ee3bea1`+`38492116`+`78924fdd`+`548cd2da`) + +§二·八 清单 1–3 与 5 逐条落定: + +- `level_runner.gd`:`_resolve_template_row` 与 `active_template_name/index` 删除,新增 `_assign_generated_graph(row, seed)`(`db.level_gen_params_row(L)` 取参数档 → `NodeMapGenerator.generate(params, seed)` → `LevelTable.validate_graph(graph.nodes)` 违规 `push_error`+返回 false,无任何兜底图);`start_level(level_index, seed, base_override)`/`start_level_external(..., defer_entry, resume_state)` 的 `template_pick` 尾参删除;`_entry_node`→`_entry_nodes() -> Array[Dictionary]`(全部无入边节点,多入口首跳即选路);`_node_id` 取 `id` 句柄,`_out_ids`/`_out_nodes`/`visited_ids`/`pick_next_node`/`_restore_to_stop`/`_bfs_layers` 同句柄空间随动,单链隐式出边(数组序兜底)整体退役;enc `node_depth` 取节点 `depth` 值、键名不变。 +- `adventure_runner.gd`:`_first_script` 字段与参数读入、`template_pick` 计算与传递全删;断点快照 `template_pick` 键 → `graph_gen_v2: 1` 代差标记键;`resume_adventure` 首检该标记,缺键旧断点返回 false+`push_error`(禁按新句柄空间静默回放)。 +- `main.gd` 删 `first_script` 参数构造(种子三分判定 `:1476-1486` 零改动,首局恒 42);`save_manager.gd` 首次冒险位注释随 T2 第一口已换代。 +- 件核:全仓 `first_script`/`template_pick`/`active_template` 零引用;`level.tres` 三行无 `templates` 键;`sim/level_autoplay.gd` 的 `boss_depth` 读数键由 `node_depth` 改 `depth`(该处曾是模板时代键名残留,切源后读不到值=测量面静默漂移,随 S7 一并清)。 + +## 二·十 T3 断言面换代(S1–S8 全数落位) + +| 清单项 | 宿主与落位 | 换代后断言面 | 变异拦截面 | +|---|---|---|---| +| S1 | `tests/integration/node_map_templates_test.gd` 整宿主重写 | ①-⑥ 模板段退役;⑦ 收束置位三条保留(措辞换「首局恒走固定种子 42」);宿主现名不变(manifest 零新增登记,改名归反哺点⑧) | M5/M7 | +| S2 | `_level_active_nodes` 三副本(`level_shop_economy`/`adventure_feats`/`round_flow_skill_pool`) | 一律改经 `NodeMapGenerator.generate(db.level_gen_params_row(L), 42)` 取图;消费点深度键 `node_depth`→`depth`;两宿主内零调用方的死件 `_boss_depth` 随删 | — | +| S3 | `level_shop_economy` 商店段 | 三条性质断言(终点前驱恰一店/商店总数=终点数/全路径恰穿一店)× L1–L3 参数档 × 种子 42+42–61 扫描;硬编码 8/9/穿节点 8/L1 行集退役;行进面「当前节点型别=shop 且出边恰一条指终点」 | M2/M3 | +| S4 | `level_shop_economy` 形状段 | 节点数/五型计数/岔口数/终点数改生成图读数性质(含「L1 终点恰一、L2/L3 含岔口」V4 投影),非空前置在位 | — | +| S5 | `level_shop_economy`〔v11〕+`adventure_feats`〔fv24〕 | 敌侧=解析落带 ≥ 请求深度(禁顶 clamp)、板侧=精确命中、多终点 Boss 带键两两互异;`adventure_feats` 原「行集内每节点在 board_gen+enemy 有精确行集」改走 `resolve_enemy_rowset`/`resolve_board_gen` 真实消费链+扫描非空前置 | 〔v11〕两条已按批内变异验证见红(前节记录) | +| S6 | `node_map_templates` 新确定性套 | 同档同种子两次产图逐位同图/换种子即变图/节点携唯一句柄+depth/起关生效图=生成器直取(单一图源)/起关产图零计数器消费/入口候选数=参数档 `entry_count`+第二入口句柄显式进入/种子 42 两开局同图/断点存→恢复→再产图同图/缺代差键旧断点拒绝/表无 `templates` 键 | M1/M5/M6/M7 | +| S7 | `sim/level_autoplay.gd`、`sim/adventure_monte_carlo.gd`、`probe/shot_probe.gd`、`probe/ui_click_probe.gd` | `template_pick` 尾参退役;MC `level_templates`→`level_maps`(值 `关卡#主种子`);route 轴沿句柄升/降序;探针「L2 商店为 Boss 前必经位」假设改性质措辞;`probe/board_shot_probe`、`probe/type_glow_shot_probe` 起关尾参残留清理 | — | +| S8 | `breakpoint_resume`(新增 P7 六断言)、`pool_case_d`、`feat_vouchers`、`cross_system_flow:79`、`meta_progression_forge:316/:323`、`curio_refresh_paid`、`save_manager_domain` | `first_script` 键清退;断点夹具 `template_pick`→`graph_gen_v2`;meta 参数面 extra 键样换 `treasure_unlocked`(「入口特有键随 extra 原样并入」判据不动);P7 钉「快照无已抽模板键+代差标记在档+停点句柄与已到序往返+续玩重生成同图+旧断点拒绝+同种子重开局同图」 | M6 | + +补充两条断言(V2/V6 拦截面补位,提交 `38492116`):原「入口停点候选 ≥1」不足以拦「候选写死单入口」,改判「=参数档 `entry_count`」并加点第二入口;`adventure_feats` 新增 `_drive_to_pref` 真实选路驱动,据此落「进战载荷两样=关卡序号+节点深度,且命中节点句柄≠深度」〔v6〕与奖励支路经停三选一在途两条。 + +宿主读数:`node_map_templates` 21 checks、`adventure_feats` 138、`breakpoint_resume` 全绿、`pool_case_d`/`feat_vouchers`/`cross_system_flow`/`curio_refresh_paid` 21/`save_manager_domain` 101/`meta_progression_forge` 133/`round_flow_skill_pool` 127/`table_structure_guard` 67/`level_map_type_vis` 26/`level_map_info_fog` 19 全绿;`level_shop_economy` 见下节。 + +## 二·十一 T3 收口:`level_shop_economy` 宿主换代(147→176 checks) + +换代后该宿主的图源单点 = `_generated_graph(level_index, seed)`(`db.level_gen_params_row(L)` × 种子),`_level_active_nodes` 走该单点取种子 42 的现行图;段内新增一批图读数辅助(`_entry_ids`/`_terminal_ids`/`_fork_ids`/`_type_tally`/`_path_shop_count`/`_all_entry_terminal_paths`/`_path_in_graph`/`_coverage_scan`/`_enemy_band_covers`/`_board_row_exact`),行进面与枚举面共用同一判据口径。 + +- S4 形状段:`L2 节点数 = 10`/`战斗节点数 = 5`/`普通战斗 6+Boss 恒一`/`恢复 1+奖励 1+商店 1`/`真实岔路 = 0`/`L1 行集零改动` 六类写死读数退役,改为「五型计数合计 = 节点数」「战斗节点数 ≥ 参数档 `battle_floor`」「Boss 节点数 = 参数档 `exit_count`」「岔口(出度 ≥2)≥1」「L1 终点恰一」「终点深度 = 参数档 `layers`」,每条都带扫描面非空前置(`L%d 现行起关图取数非空`)。 +- S3 商店段:三条性质断言 × 三关参数档 × 种子 42+42–61 全扫描(违例计数落进断言消息,图数与路径数在案:60 图 / 1413 条入口→终点路径),另保留行进面两条(到店当前节点型别=shop 且出边恰一条指终点;min/max 两轴路径逐跳为图出边、末节点为 Boss、穿店恰一)。 +- S5 覆盖段:`跨表行完整(7 节点)` 改 `_coverage_scan` 逐关读数——敌侧「落带 ≥ 请求深度」、板侧「精确命中且 `node_depth` 等值」,并逐关登记颗数非空;终点 Boss 行集断言按图终点深度解析(`L2 全部终点深度 … 的 Boss 行集`)。 +- 收口一件:换代过程中宿主内一度写过 `MUTATION-A/B/C/D` 内联自改生成图的脚手架与两条配套 MUT 断言(把变异开关埋进测试面=测试自己造数据,属反模式),已由 `d48bf10f` 整体删除,V5 证据改由生产码注入取证(见下表 M2/M3)。 + +## 二·十二 变异验证记录表(卡② 补挂七条;T1 四条与〔v11〕两条见 §二·五/§一) + +跑批脚本 `game/tests/.gates/mutate_iter35_card2.py`(注入→最窄宿主→还原→逐条自检,跑后 `git status` 核产品码四件零改动;脚本本身属临时件,收口前删除)。红行取被测宿主自身的 FAIL 文本,不取包装层退出码。 + +| # | 注入点 | 变异内容 | 最窄宿主 | 结果与红行 | +|---|---|---|---|---| +| M1 | `level_runner.gd` `_candidates = entries`(两处入口停点候选,改首条) | 多入口候选写死单入口 | `node_map_templates_test` | 红(命中):`入口停点候选数=参数档入口个数(L3 档 2——多入口首跳即选路,禁写死单入口)` | +| M2 | `node_map_generator.gd` 产图返回前把 shop 型别改 rest | 终点前驱改非店 | `level_shop_economy_test` | 红(命中):性质①「每终点直接前驱恰一家店」违例 | +| M3 | 同上,把首个 battle 型别改 shop | 某路径加第二家店 | `level_shop_economy_test` | 红:性质②「每图商店节点数=终点数」违例 60/60 图;性质③「每条入口→终点路径恰穿一家商店」违例 738/1413 条;行进面 `L2 min/max 路径穿商店恰 1 家` 同批转红 | +| M4 | `level_runner.gd` enc `"node_depth": int(node.get("depth", 0))` → 取 `id` | enc 定位信息取句柄 | `adventure_feats_test` | 红(命中):`进战载荷两样=关卡序号+节点深度(实测 depth=… 句柄=…)〔v6〕` | +| M5 | `node_map_generator.gd` `pure_stream(seed_val, SCOPE_STRUCTURE)` → `open_stream("node_map")` | 产图改依赖统一流计数器号位 | `node_map_templates_test` | 红(命中):`同参数档同种子两次产图逐位同图(D2 执行边界)` | +| M6 | `adventure_runner.gd` `if int(bp.get("graph_gen_v2", 0)) != 1:` → `if false:` | 旧断点缺代差标记键却放行回放 | `breakpoint_resume_test` | 红(命中,复跑取证到断言名):`P7 缺生成图代差标记键的旧断点显式拒绝(禁按新句柄空间静默回放)`(1/56 项失败) | +| M7 | `level.tres` 首行偷留 `"templates": [{"nodes": []}]` | 模板数据未清尽 | `node_map_templates_test` | 红(命中):`level 表三行均无 templates 键(模板数据已清出)` | + +卡片 §8 变异清单九条的落位:V1 两条(T1 已录)、V11 两条(覆盖批已录)、V2/V5×2/V6/V7/V8/V9 共六条(本表 M1–M7,V5 拆两条)。 + ## 三、遗留读数义务