test(tools): rowgeom 逐行几何基线 + 长度不变式按类别判定
新增 `OffscreenChecks -run rowgeom`(§13.6 第 1 项),把 7 个面板的每个矩形的 每个字段导出为文本基线并逐项比对,作为"完整结构合并 / 重写布局算式"的前置护栏。 两层覆盖 - 细节层:6 信号 1 网格、7 面板全开、参数行展开、3 个真实固定点、折起+展开各一份, 983 条键(-data MF4-Record.MF4 时 1304 条),失败时直接给出字段名+行号+新旧值; - 规模层:全部信号合并成 1 个网格(MF4 = 566 行),每面板一个 FNV-1a 摘要 + 行数, 任何一行变动都会改哈希,同时不产生几十万行基线。 负向自检(证明护栏不是空转) - 篡改基线副本 `mark.markerRowCount=3 → 2` ⇒ `CHANGED … mismatches=1` + FAIL。 顺带修正第 36 轮定得过严的不变式 - `rowRefs` 是重载字段:MARK 面板用它表示"信号分组",真正的条目行在 markerRows, 且只填 rowNameRects / rowNameCloses,其余 14 列必须为空; ⇒ `panels` / `panelscroll` 的"18 列全等"改为按 `PanelStyle::markerGroups` 分流判定, 失败时打印 15 个计数字段便于定位。 - 导出器/不变式一律**逐列按自身长度**遍历(按 rowRefs.size() 索引其它列会越界, 这是本轮第一次 0xC0000005 的根因)。 测试用例里的两处修正 - `MERGE_LANES` 之后补 `SynchronizeView(true)`:`SetMode` 只重建 TabConfig 的网格配置, `PlotView::m_lanes` 要等下一次布局才刷新; - 场景 B 重新播固定点:`ShowSignals()` 先 `SetAllVisible(false)`,而"全部不可见 ⇒ 丢弃网格" 是 RebuildLanes 的既有设计,网格级状态随之清空(不是缺陷),因此不能跨场景依赖。 验证 - make release:零 warning,785,408 B 不变(本轮只动工具/检查与文档) - make -C Tools clean && make -C Tools:零 warning - UnitTests:checks=260 failed=0 cases=19 - OffscreenChecks -all:7 检查 / 127 断言全 PASS(原 6 / 101) - rowgeom -mode compare:默认数据 983+7 键、MF4 1304+7 键,0 差异 - panels -mode compare:7 个面板像素哈希 + 几何逐项不变 文档:Code_Review_Plan §九、Progress 第 37 轮、Report §14、agent_mem 第 37 轮、Tools/README §4.1/4.3/4.4
This commit is contained in:
1 parent
221f9d2410
commit
353c553721
6 files changed
+821
-48
No files matched your search
@@ -271,3 +271,39 @@
|
||||
|
||||
本轮先用 `AppendRow()` 把**真实隐患**("某分支漏推一列")消除,
|
||||
完整结构合并留待"逐行几何基线"检查就绪后再做。
|
||||
|
||||
---
|
||||
|
||||
## 九、第 37 轮追加(2026-11-04):逐行几何基线(§13.6 第 1 项)
|
||||
|
||||
> 触发:用户要求「按照你的建议继续推进」。§13.6 第 1 项 = 逐行几何基线,
|
||||
> 它是 §13.3「完整结构合并」与「重写布局算式」的前置护栏。
|
||||
|
||||
| 节点 | 内容 | 验收标准 |
|
||||
| --- | --- | --- |
|
||||
| **P29** | 新增 `OffscreenChecks -run rowgeom`:把 7 个面板**每个矩形的每个字段**导出为文本基线,逐项比对 | `-mode record`/`-mode compare` 无差异;**篡改基线必须报错**(负向自检) |
|
||||
| **P30** | 修正长度不变式的判据:从"18 列全等"改为**按排版类别**判定 | `panels` / `panelscroll` 仍全绿,且对 `MARK` 面板不再误判 |
|
||||
|
||||
### 9.1 基线的两层覆盖
|
||||
|
||||
| 场景 | 数据 | 记录内容 | 用途 |
|
||||
| --- | --- | --- | --- |
|
||||
| **A:细节** | 前 6 条信号合并成 1 个网格,7 个面板全开、参数行展开、3 个固定点、折起/展开各一份 | 每行每列的精确矩形(`Temp/tools/rows-baseline/rowgeom-baseline.txt`,983 条键) | 定位级:一眼看出"哪一行哪一列偏了几个像素" |
|
||||
| **B:规模** | **全部**信号合并成 1 个网格(MF4 = 566 行) | 每个面板一个 FNV-1a 摘要哈希 + 行数/固定点行数 | 覆盖级:任何一行变动都会改哈希(不产生几十万行基线) |
|
||||
|
||||
### 9.2 本轮新增硬约束
|
||||
|
||||
1. **改面板几何(宽高算式 / 行距 / 内边距 / 折起规则)前后必须跑**
|
||||
`OffscreenChecks -run rowgeom -mode record|compare`。
|
||||
基线是**检测器**不是黄金图:变化是**预期**时要重新 record,并在提交信息里说明原因。
|
||||
2. **`rowRefs` 是重载的**:「列表式面板」用 `rowRefs` 表示"每个信号一行",
|
||||
而「自由标记面板」用它表示"每个信号一个分组",只填 `rowNameRects` / `rowNameCloses`,
|
||||
其余 14 列**必须为空**(真正的条目行在 `markerRows`)。因此任何"平行数组长度"不变式
|
||||
**必须按 `PanelStyle` 分类判定**,不能写"全部 18 列全等"。
|
||||
3. **`ExecuteToolbarAction(MERGE_LANES / SPLIT_LANES)` 之后、读 `LaneCount()` 之前,
|
||||
必须先 `SynchronizeView(true)`**:`SetMode()` 只重建 `TabConfig` 的网格配置,
|
||||
`PlotView::m_lanes` 要等下一次布局/绘制才刷新。
|
||||
4. 检查里**不要依赖"上一个场景的网格级状态还在"**:`Session::ShowSignals()` 先
|
||||
`SetAllVisible(false)`,而"全部不可见 ⇒ 丢弃网格"是既有设计
|
||||
(`RebuildLanes` 的 MERGED 分支),固定点/面板开关会随之清空 —— 该场景要**重新播**。
|
||||
|
||||
Reference in new issue
Block a user