补提交(写卡段欠账): 需求卡片-棋盘格边长口径收口批-2026-10-30 入库——待办清单:326 引用在先而文件一直未跟踪,主区盘上存在故 08c 流水线闸查盘放行,worktree 冷检出无此件即红(iter44 收口期 08c 红的成因);跨区失配随本地 CI 化自然消解(CI 在主区跑,盘上=库内同一面),本件补齐引用实体的历史在库

This commit is contained in:
DKChan committed 2026-10-30 16:47:20 +08:00
1 parent bee73db51b
commit 7a2d19fd12
1 file changed
+183
@@ -0,0 +1,183 @@
# 需求卡片——棋盘格边长口径收口批(探针门槛纠偏+格边长算式单点+冒烟扩四档板型)
状态行:v1.0 定稿——零待裁点(2026-10-30 用户裁:①探针不扩到 L3 推关;②最紧档 14×14 的可读断言落单元四档+探针实板推定两处;③算式单点提取用私有静态名,依据见 §2 第 5 条)
接收方:待办清单条目「棋盘格边长三方取值不一致——待扩板定档处置(2026-10-06 登记,来源=批次移交)」(`待办清单.md` 在册,状态「待写卡」)
来源:**设计事实源**=`design/gdd/ux/battle.md`「棋盘格尺寸公式」节(Last Updated 2026-10-29;格边长口径的**唯一事实源**——公式、可读下限 30px、结构钳制 [26,46] 三项都在此节)。指路文档(2026-10-26 已归一、不再存算例)=`design/art/art-bible.md` §8.1/§8.2、`design/gdd/systems/表现与支撑/HUD框架.md`。四档板型事实源=`game/data/tables/board_gen.tres`。
## 1. 目标与完成定义
这批做什么:把「棋盘格边长」在代码侧残留的两处旧口径收干净。文档侧已于 2026-10-26 归一(口径只剩 battle.md 一节),代码侧还差两件——探针的可读门槛仍是 12×12 时代的 36px(比 battle.md 的可读下限 30px 严 6px,属用旧值当新标准),格边长冒烟只跑 L1/L2(13×13 与 14×14 两档板型无断言)。本批顺带把格边长算式收成单点(现在它内联在 `set_cell_area` 里,任何「在别的板型/别的面积上求值」的需求都只能复写算式=造第二口径)。
**行为零变化**:算式逐位不变,`set_cell_area` 的副作用顺序(英雄脚锚重置 → `_refresh_slab` → `_update_world_size`)零改动,玩家可见画面零变化。
完成定义(全部满足才算完):
1. 代码侧可读门槛=30px,与 battle.md「可读下限 30px」一致;旧值 36 在 `game/` 下零残留。
2. 格边长算式只剩一处落点(`BoardView._cell_for`),`set_cell_area` 只调它;探针与单元测试不再各自复写算式。
3. 13×13 与 14×14 两档进入断言并在当轮真实跑批中执行通过(单元四档+探针实板面积推定两条)。
4. 代码域闸全绿;`tools/gdstyle_baseline.txt` 中 board_view.gd 各键只许持平或下降(MATCH——`max-public-methods` 保持 27)。
5. 产出物三份落 `reports/`(实现报告/反哺点清单/验收审计报告),独立验收审计未过不合并。
**编队注记与估时**:估时 **0.5 个工作日**(T0 0.1/T1 0.15/T2 0.1/T3 0.1/T4 0.05),远低于迭代冻结线(5 个工作日),可编批;编入哪个迭代由迭代编排段定。本批触面=`game/presentation/views/board_view.gd`+`game/probe/layout_probe.gd`+`game/tests/unit/core/board_gen_reward_test.gd`+`game/tests/README.md`(写卡段已同批入表),与在飞批次无文件交叠需编排段复核。
## 2. 现状事实
全部行号为 **2026-10-30 实查**——本批编入后须由 T0 按 T0 时点 master 重测重锚。
1. 算式内联在 `game/presentation/views/board_view.gd:191-209`(`set_cell_area`):`:194` N=`maxi(width,height)`、`:195` `sep := SEP`(`SEP := 2`,`:34`)、`:196-197` `d := DEPTH_PX`(`8.0`,`:37`)与 `reserve := 24.0 + d`、`:198` 一条 `int(floor((minf(avail.x - 12.0 - d, avail.y - reserve) - float((n - 1) * sep)) / float(n)))`、`:199` `clampi(cell, 26, 46)`。副作用尾链 `:200-209`(英雄脚锚重置/`_refresh_slab`/`_update_world_size`)。
2. 生产调用路径两条:`game/presentation/views/board_zone_view.gd:91-92`(`board_area.resized` → `set_cell_area(_board_area.size)`)与 `game/presentation/views/board_view.gd:250`(`rebuild` 末尾 `set_cell_area(size)`)——传入的都是棋盘视图实际可用区尺寸,`board_view` 为 `PRESET_FULL_RECT` 子级,故 `board_view.size` 即生产传入值。
3. 探针门槛:`game/probe/layout_probe.gd:15` `const MIN_CELL := 36.0`,注释自陈「battle.md §棋盘格尺寸公式 1280 档 12×12 → 36px」;`:92-94` 断言 `cell < MIN_CELL` 记红。探针只进 L1(`:27` 起始冒险)、`:31` `press_candidate(0)`,故实跑只会遇到 10×10(格边约 45px),门槛 36 从未在 30–35px 区间生效过。
4. 格边长冒烟:`game/tests/unit/core/board_gen_reward_test.gd:53-69`(`_smoke_layout_cell_formula`):`:57` `for L in [1, 2]`、`:58` `generate(L, 0, ...)`、`:60` 样本 `avail := Vector2(1036, 460)`、`:63` 读 `board_view.get("_cell")`、`:64-66` 网格高 ≤ 可用高−24、`:67-68` 格边长 ∈ [26,46]。13×13 与 14×14 两档从未进入断言。
5. **S13 顶格事实(本机 gdstyle v0.4.0 实测)**:`tools/gdstyle_baseline.txt:22` 登记 `game/presentation/views/board_view.gd|quality/max-public-methods = 27`,与实测公开方法数 27 相等。对同一文件副本加一个公开静态函数后实测升到 **28**(WORSENED 红);改名为下划线前缀(`_cell_for`)后实测仍为 **27**(零新发现)。故算式提取必须用私有名。
6. 四档板型取档(`game/data/tables/board_gen.tres` 实查 (level_index, node_depth) → 尺寸):L1 depth 0–3=10×10、L1 depth 4–6=12×12、L2 depth 0–9=12×12、L3 depth 0–8=13×13、L3 depth 9–13=14×14。即 `generate(1,0)`=10、`generate(2,0)`=12、`generate(3,0)`=13、`generate(3,9)`=14。
7. 规格侧:`battle.md:137-146` 公式与两项判据——结构钳制区间 [26,46]px(`:143`,管算式不越界)、**可读下限 30px**(`:144`,管玩家能否看清,与钳制分开);`:148-152` 算例表按「1280 档可用高 486px」推算 43/36/33/30,文内明标「随布局与板型变化,不是契约值」。
8. 实机可用面积与算例不同源:`game/presentation/ui_assembler.gd:20-28` 结构为 B 区 252px + C/D 两列占余高(该文件 `:24` 注释写明 548px),D 列内 `board_zone_view.gd:24-36` 再减 AP 条 44px 与 4px 间距——与 battle.md 算例假设的 486 可用高存在偏差(与待办清单在册的「B 区高度 270 vs 252」同源)。本卡不把算例当契约,实板可用面积一律以探针实读 `board_view.size` 为准。
## 3. 设计契约(违反即返工,标 🔴 触碰=L3 停机呈报)
- 🔴 **算式单点**:格边长算式只在 `BoardView._cell_for` 一处;`set_cell_area` 只调它。探针、测试、任何新调用方都不得复写这条算式(复写=造第二口径,本批立项原因就是三处口径打架)。
- 🔴 **两个数不得合并**:可读下限 30px(battle.md 判据)与结构钳制 [26,46]px(算式不越界)是两个概念。前者只出现在探针门槛与断言里,后者只出现在 `_cell_for` 内;禁止用钳制区间替代下限判据,也禁止把下限塞进 `cell_for` 的 clamp。
- 🔴 **私有名固定**:提取函数名必须是 `_cell_for`(下划线前缀)。依据=§2 第 5 条的实测:公开名即令 `max-public-methods` 27→28 恶化。实现期「顺手改成公开方法更好看」=L3。
- 🔴 **行为零变化**:`set_cell_area` 的副作用顺序与数值逐位不变;`rebuild`/`resized` 两条调用路径不改;画面像素零变化。
- 🔴 **测试削弱申报制**:允许改动的旧断言全集见 §8「测试削弱申报」,未申报的删改由独立验收审计判红。
- 🔴 **禁变异类测试与撤销类取证**:不得靠回退 hunk 或注入破坏证明断言有效。
## 4. 范围边界
做:算式提取为 `_cell_for` 并改调;探针门槛 36→30 与注释改指 battle.md;探针新增「实板可用面积下 13/14 板格边长推定」断言与 board_view 零尺寸前置;格边长冒烟扩到四档板型并加算式单点等价断言;`game/tests/README.md` 能力行入表(写卡段同批,见 §5)。
不做(明示去向):
1. **探针扩到 L3 推关**——2026-10-30 用户裁不做:成本是探针要真打穿两关(main 无跳关入口),且一旦红因是推关而非布局会污染该闸;最大板可读面改由 §7.3 的推定断言承担。
2. **battle.md 算例表改数**——实现批禁写 `design/`;实测与算例的偏差走 §5 反哺点通道。
3. **四档板型数值调整**——`board_gen.tres` 板尺寸由设计侧定,本批只读不写。
4. **B 区高度 252 vs 270**——另一条在册待办(迭代 43 批后待裁三点),本批不碰。
5. **`set_cell_area` 副产物顺序调整**——零触碰。
6. **MC/数值验证**——无数值改动零跑。
## 5. 关联文档同步面
| 文档 | 关联点(本批实现会改变它的哪条陈述) | 同步义务 |
|---|---|---|
| design/gdd/ux/battle.md(设计权威——实现批禁直改) | ①`:148-152` 算例表按「可用高 486px」推算 43/36/33/30,而实机 D 列结构为 548px(§2 第 8 条)——探针实测格边长若与算例不符,是算例随布局漂移而非代码错;②「可读下限 30px」(`:144`)条本身不变,本批正是向它对齐 | 反哺点通道:把探针 L1 实测格边长与 13/14 推定读数逐条列进 `reports/iter<N>-反哺点-<日期>.md`(改哪一节=`:148-152` 算例表、改成什么=填实测值或标注「按旧布局口径」、依据=实测读数),用户会话裁决后归文档批落文 |
| game/tests/README.md(机械面——归写卡段维护) | 新增能力行「战斗屏三区几何与棋盘格边长(分辨率两档×四档板型)」,覆盖域表 HUD框架.md 行同步补名 | 写卡段已于本卡成文同批入表,实现批零增删零改行 |
| design/gdd/systems/表现与支撑/HUD框架.md、design/art/art-bible.md §8.1/§8.2(已归一为指路) | 本批不改二者的任何陈述(2026-10-26 归一后它们只写规则与指针,不存算例与定值档) | 无(本行占位——按规约查不出也要写明) |
## 6. 卡前文件结构图
| 文件 | 职责 | 新增/复用 | 行为改动? |
|---|---|---|---|
| game/presentation/views/board_view.gd | 修改:`set_cell_area` 内联算式抽成 `static func _cell_for(n, avail) -> int`,`set_cell_area` 改调;注释补「算式唯一落点」句 | 复用既有(抽自本文件既有代码,不新增文件/类) | 否(算式逐位相同——对照表行 2 的等价断言承载) |
| game/probe/layout_probe.gd | 修改:门槛 36→30+注释改指 battle.md;新增 board_view 零尺寸前置与 13/14 板格边长推定断言 | 修改 | 是(守卫面变化——对照表行 1/4) |
| game/tests/unit/core/board_gen_reward_test.gd | 修改:格边长冒烟循环扩四档板型+板型一致断言+算式单点等价断言 | 修改 | 是(测试面——对照表行 2/3) |
| game/tests/README.md | 修改:能力清单加一行+覆盖域表 HUD框架行补名 | 修改 | 否(机械面文档,写卡段同批完成) |
不触碰:`board_zone_view.gd`、`ui_assembler.gd`、`data/tables/board_gen.tres`、全部 `core/` 与 `data/` 代码、其余探针与测试套件。
## 7. 任务卡 T0..T4
### 7.1 T0——读数重锚与取档对账(估时 0.1 个工作日)
- [ ] 按 T0 时点 master 重测重锚 §2 全部行号:`layout_probe.gd:15`/`:92-94`/`:27`/`:31`、`board_view.gd:34`/`:37`/`:191-209`/`:250`、`board_zone_view.gd:91-92`、`board_gen_reward_test.gd:53-69`。
- [ ] 四档取档复核:对 `db.combat.board_gen.resolve_row(L, D)` 逐组取 (1,0)(2,0)(3,0)(3,9),实测返回 `board_width` 依次为 10/12/13/14——不符=L3 停卡退回写卡段。
- [ ] 改前基线读数(孤立验证):`python tools/gdstyle_gate.py`(board_view.gd `max-public-methods` 实测 27 持平)+单件跑 `board_gen_reward_test`(绿)+单件跑 `layout_probe`(两档绿)。三条读数进实现报告 T0 节。
- 取用:本卡 §2。产出:重锚后的行号与三份改前读数(T1–T4 对拍基准)。
### 7.2 T1——算式单点提取(估时 0.15 个工作日)
- [ ] `board_view.gd` 新增 `static func _cell_for(n: int, avail: Vector2) -> int`,函数体=`:195-199` 五行算式逐字搬入(`SEP`/`DEPTH_PX` 仍读本文件既有常量,`clampi(..., 26, 46)` 留在该函数内),返回 `int`。
- [ ] `set_cell_area` 的 `:194-199` 六行替换为 `_cell = float(_cell_for(maxi(_board.width, _board.height), avail))`;`:200-209` 副作用尾链一字不动。
- [ ] `:189-190` 注释块补一句:算式唯一落点=`_cell_for`(探针与单元测试共用);名字带下划线是 S13 `max-public-methods` 27 顶格的约束,禁改公开名。
- [ ] 孤立验证:单件跑 `board_gen_reward_test`(既有四套断言全绿=算式等价性证明)+`python tools/gdstyle_gate.py`(board_view.gd 各键持平,`max-public-methods` 仍 27)。
- 取用:T0 读数。产出:`BoardView._cell_for(n: int, avail: Vector2) -> int`(公开静态调用面,T2/T3 逐字消费)。
### 7.3 T2——探针门槛与最大板推定(估时 0.1 个工作日)
- [ ] `layout_probe.gd:15` 改 `const MIN_CELL := 30.0`,注释改为「可读下限 30px(battle.md §棋盘格尺寸公式;结构钳制 [26,46] 管算式不越界,是另一回事)」。
- [ ] 顶部加 `const BoardViewScript := preload("res://presentation/views/board_view.gd")`(静态调用载体)。
- [ ] `_check_one` 在既有格子断言之后追加两段:①board_view 零尺寸前置——`bv.size.x <= 0.0 or bv.size.y <= 0.0` 时记问题「board_view 零尺寸(可用面积不可信,格边长推定无依据)」;②推定断言——对 `n in [13, 14]` 取 `BoardViewScript._cell_for(n, bv.size)`,`< int(MIN_CELL)` 即记问题,消息含实板可用面积、板型、算出的格边长与下限。
- [ ] 收口 PASS 消息补一句「13/14 板推定 ≥30px」。
- [ ] 孤立验证:单件跑 `layout_probe`(两档全绿)+`tools/probe_gate.sh` 默认段(含本探针在内的默认段退出码 0)。
- 取用:T1 `_cell_for`。产出:绿的两档探针日志(T4 对拍基准)。
### 7.4 T3——格边长冒烟扩四档(估时 0.1 个工作日)
- [ ] `_smoke_layout_cell_formula` 的 `:57` 循环集改为四档取样表:`[{L:1,D:0,n:10}, {L:2,D:0,n:12}, {L:3,D:0,n:13}, {L:3,D:9,n:14}]`(按 §2 第 6 条的实表取档)。
- [ ] 每档追加两条断言:①板型一致——`maxi(b.width, b.height) == 取样 n`(表改动导致取样落错档时红);②算式单点——`int(cell) == BoardViewScript._cell_for(n, avail)`(`set_cell_area` 写入值与纯函数返回同值)。
- [ ] 既有两条断言(网格高 ≤ 可用高−24、格边长 ∈ [26,46])逐字保留,仅把消息前缀从 `L%d` 扩成 `L%d D%d`;`:60` 样本 `Vector2(1036, 460)` 不改(本卡把「真实可用面积」的可读面交给探针,样本只承担算式不溢出面)。
- [ ] 孤立验证:单件跑 `board_gen_reward_test`(四档全绿)。
- 取用:T1 `_cell_for`、T0 取档对账。产出:四档冒烟日志(T4 对拍基准)。
### 7.5 T4——批末收口与产出物落位(估时 0.05 个工作日)
- [ ] 批末代码域闸:`tools/run_all_gates.sh --code` 全绿(本批改动含 `game/` 下非 `.md` 行为载体 → 代码域;02 单元与集成按关联档选跑 `board_gen_reward` 套件,冒烟/系统测试/静态扫描三件恒跑)。里程碑步出口跑一次全套;波内修复只做出红最小单元的最窄确认。
- [ ] S13 键账对账:board_view.gd 各键持平(`max-public-methods` 27 不变、`max-class-variables` 32 不变、无 NEW 键);探针与测试不在 S13 扫描面。
- [ ] **产出物落位卡**(轻闸全绿后、合并前写齐,方算收口):
- `reports/iter<N>-实现报告-<日期>.md`——各卡状态+T0 三份改前读数与各卡改后读数对拍+探针实读的 `board_view.size`(两档视口)与 L1 格边长实测值+13/14 推定值+实机目检总清单(登记不阻塞:「第三关 14×14 板格面数字清楚可辨」一项,时间由用户自定)。
- `reports/iter<N>-反哺点-<日期>.md`——§5 同步面第 1 行(battle.md 算例表 vs 实测)逐条有落点。
- `reports/iter<N>-验收审计-<日期>.md`——独立验收审计(未参与实现的会话或子代理执行,未过不得合并)。
- 取用:T1–T3 全部产出。产出:代码域闸回执+三份 reports/ 产出物。
## 8. 验证闸(改动—验收对照表)
本批三处改动全部落在守卫面(探针门槛/测试覆盖/算式落点),游戏行为零变化,故无新玩法验收;用户目检一项登记不阻塞(T4)。对照表 5 行对应 §1 完成定义第 1–5 条。
| # | 需求点 | 改动(文件:行/行为) | 验收测试(名称+落点+尾缀) | 层级 | 真实入口 | 判据绑定面 | 能力行 |
|---|---|---|---|---|---|---|---|
| 1 | 探针可读门槛与 battle.md 对齐(36→30) | `layout_probe.gd:15` 常量与注释;`:92-94` 断言文本沿用 | 「layout_probe 两档几何不变量」`layout_probe.gd:_ready`(尾缀〔格边长 V1〕) | 探针 | `godot --headless --path game res://probe/layout_probe.tscn` | 探针经真实战斗屏装配读到 `board_view.cell_size` 且 ≥30px(下限判据直接作用于实机取值) | 新增:战斗屏三区几何与棋盘格边长(分辨率两档×四档板型) |
| 2 | 算式单点(`_cell_for`) | `board_view.gd:191-209` 抽函数并改调;`:189-190` 注释补唯一落点句 | 「格边长算式单点等价」`board_gen_reward_test.gd:_smoke_layout_cell_formula`(尾缀〔格边长 V2〕) | 单元 | `godot --headless --path game --script res://tests/unit/core/board_gen_reward_test.gd` | `set_cell_area` 写入的 `_cell` 与 `BoardView._cell_for(n, avail)` 返回值逐档严格相等(同一事实两路读取,分叉即红) | 新增:战斗屏三区几何与棋盘格边长(分辨率两档×四档板型) |
| 3 | 13×13/14×14 进入冒烟 | `board_gen_reward_test.gd:53-69` 循环集改四档取样+板型一致断言 | 「格边长冒烟四档板型」同函数(尾缀〔格边长 V3〕) | 单元 | 同上 | 13/14 两档首次被断言:取档尺寸与实表一致、网格高 ≤ 可用高−24、格边长 ∈ [26,46](此前从未执行) | 新增:战斗屏三区几何与棋盘格边长(分辨率两档×四档板型) |
| 4 | 最大板可读推定(实板可用面积) | `layout_probe.gd:_check_one` 新增 board_view 零尺寸前置+`n∈{13,14}` 推定断言 | 「最大板格边长推定」同探针(尾缀〔格边长 V4〕) | 探针 | `godot --headless --path game res://probe/layout_probe.tscn` | 以探针实读 `board_view.size` 代入 `_cell_for(13/14, size)` 得 ≥30px(真实容器尺寸下的最大板可读面——不推关即可覆盖) | 新增:战斗屏三区几何与棋盘格边长(分辨率两档×四档板型) |
| 5 | 批末收口 | 全批 | 代码域闸:`tools/run_all_gates.sh --code` | 全量闸 | `tools/run_all_gates.sh --code` | 所选域全绿回执(`game/tests/.gates/receipt.json`) | 新增:战斗屏三区几何与棋盘格边长(分辨率两档×四档板型) |
**测试削弱申报**(实现期允许的旧断言改动全集,超出即审计判红):
1. **探针门槛 36→30=阈值放宽**,依据 battle.md `:144`「可读下限 30px」(旧值 36 是 12×12 旧锚点的误用,探针实跑从未触及 30–35px 区间,等于该门槛对大板无效)。补偿=第 4 行新增推定断言与第 3 行四档冒烟——原门槛守不住的面由两者接管。
2. 第 3 行循环集从 2 档扩到 4 档=纯增量;`avail` 样本值不改;既有两条断言(网格高、区间)逐字保留。
3. 探针新增断言=纯增量,既有格子断言与两档视口表不改。
4. 显式禁止:删任何旧断言、放宽区间 [26,46]、把格子读取从 `cell_size`/`_cell` 换成别的入口。
**独立验收审计**:入口与报告=`reports/iter<N>-验收审计-<日期>.md`;审计方=未参与实现的会话或子代理,逐行核对对照表两端、抽查判据绑定面是否绑在被测改动特有的可观测面(`cell_size`/`_cell` 取值与 `_cell_for` 返回)、核对削弱申报、确认全文无变异/撤销类取证;未过不得合并。
## 9. 异常分级
- **L1 自救**:单件跑红→定位该件最小单元修后重跑;探针单件超时→孤立复跑该件;`--only` 选跑零命中(用法错 exit 2)→修正选词重跑。
- **L2 记录继续**:同一红连续 3 次同因→在实现报告「实现决定记录」记因后继续最窄确认。
- **L3 停机写报告等用户**:
1. **机检预算互斥=上游缺陷停卡退回写卡段**——`gdstyle_gate` 出 NEW 键或 `board_view.gd|quality/max-public-methods` 升到 28(即 `_cell_for` 的下划线被去掉);本批零新增文件、零新增成员,任何键恶化都不许改基线换绿,禁开豁免。
2. **实板可读面本身不达标**——探针实测 L1 `cell_size` < 30,或实板可用面积代入 13/14 后 < 30。这是产品面问题(不是断言错),停卡呈报,禁调低下限、禁换样本凑绿。
3. **四档取档对不上**——`resolve_row(1,0)/(2,0)/(3,0)/(3,9)` 实测尺寸与 §2 第 6 条不符(表已改而本卡未跟上)。
4. **算式等价性破**——T1 后既有四套断言出现改前不存在的红,说明提取改变了算式语义。
## 10. 代拍板白名单(逐条列,超清单记实现报告「实现决定记录」)
1. `_cell_for` 内部局部变量名与注释措辞(算式、常量、clamp 数值不变)。
2. 四档取样表用字典数组还是三元组数组(取值与断言不变)。
3. 探针推定断言与零尺寸前置的失败消息文案、PASS 消息措辞(判据不变)。
4. 尾缀〔格边长 V1〕–〔格边长 V4〕的字样编排(含义不变)。
5. `BoardViewScript` 常量名(preload 载体命名)。
## 11. 待裁点
**零待裁点,开工门=U0。** 2026-10-30 用户三项裁定已定案:①探针不扩到 L3(推关成本与红因混淆,最大板改走推定断言);②最紧档 14×14 的断言落两处(单元四档+探针实板推定);③算式提取用 `_cell_for` 私有名(§2 第 5 条 S13 实测依据)。编批由迭代编排段定。
## 12. 落位与可复用性预检
**复用面**:本批零新增文件、零新增类。`_cell_for` 抽自 `board_view.set_cell_area` 既有内联算式——不能只留在原处内联,是因为探针要在「非当前板型(13/14)× 真实可用面积」上求值、单元测试要在四档板型上求值,内联形态无法复用,复写算式就是造第二口径(正是本卡要消灭的缺陷形态)。探针与测试的既有工具件(`probe_ui_util.gd`、`test_kit.gd`)与本批职责无关,不复用也不扩展。
**唯一面**:算式唯一落点=`BoardView._cell_for`;可读下限 30px 的唯一代码判据面=`layout_probe.MIN_CELL`(文本出处=battle.md `:144`);四档板型唯一事实源=`board_gen.tres`(测试按 (L,D) 取行,不复制取值)。2026-10-30 实查 `game/` 下无 `cell_for`/`_cell_for` 同名或同义函数,无第二落点。
**分层与交互面**:`_cell_for` 是无状态纯函数——零成员读写、零信号、零 RNG、零 UI 依赖、零 `load()`;调用路径=`set_cell_area`(生产)/探针 `_check_one`(经脚本常量静态调用)/单元测试(同前)。preservation:不新增跨层依赖,Core 零 UI 红线零触碰(本批不触 `core/`)。
## 13. 实现规范预算
**新件三查**:本批零新增文件——三查不适用(写「无新增件」)。
**存量触面一查**:触碰的存量件为 `board_view.gd`(S13 扫描面内)与探针/测试两件(不在 S13 扫描面)。`board_view.gd` 预期:`quality/max-public-methods` 保持 **27**(私有静态不计数,§2 第 5 条实测)、`quality/max-class-variables` 保持 32、`quality/max-branches|_paint_cell` 等函数级键持平(本批不增分支、不增成员、不增局部变量——`set_cell_area` 局部变量反而减少)。达成手段:算式整体搬出,函数体只留一行调用。
**指标例外申报**:无。
## 14. 源码级断言与探针契约面的随批义务(防漏项清单)
1. `layout_probe` 的既有两档视口表(`VIEWPORTS`)与三条几何不变量(三区非零/不越视口/互不重叠/view 含于 D 区)本批零改动——T2 只追加断言,不改判据。
2. `board_view` 的对外只读出口(`cell_size`,`board_view.gd:93-95`)是探针取值面,本批不动;测试内部读 `_cell`(测试惯例已如此,`board_gen_reward_test.gd:63`),不改为公开出口。
3. `game/tests/README.md` 能力行由写卡段同批入表(本卡成文时已落),实现批不写该文件;批末核对表上名字与实况一致。