refactor(编号): 批 4 陷阱号统一为 TRAP-<模块码>-<nn>

本批是 ② 形态迁移清的第一族(用户裁定顺序:② 里的 Trap 一族先做)

统一了什么(数字不变、只补模块码,§7.1)——改名工具 23 处 / 11 文件
- Trap 01~07 → TRAP-GD5F-01~07:属主文档 7 个标题行从此成为定义位
- 陷阱 1 → TRAP-RTC-01(SD2506 属 RTC 域,§4.2)、见陷阱 01 → TRAP-GD5F-01
- Trap 21 / Trap 19 → TRAP-NET-21 / TRAP-NET-19(引用的是活登记处
  CH395F_Trap_Records.md,号本身不变)
- 波及 Drivers/BSP/GD5F2GQ5UE/*(4 处注释)与 test/board/*(2 处)→ 已重编

三处判读后**刻意不改**(写进 §8.3,不让人当成漏网)
- docs/环境与部署/并行任务工作树方案.md 的 wip/trap22-fix 是 git 分支名,不是编号;
  这类非编号字面量要靠类型处理,与位号 T1、IEEE 负序 S2、gitlint 规则 ID 同一批
- docs/UI设计/菜单页面设计.md 变更记录行的「陷阱 3」按 §8.1 冻结不改写
- docs/硬件平台/V0.0、V0.1 网表报告里 6 处 Trap05 语义确指 TRAP-NET-05,但该目录
  是门禁与改名工具共同的排除语料 → 不越界动笔,盲区登记进注册表 TRAP 族 cursor_note

两处不是改名、是改错话(映射表类工具的典型失效:字面对了、意思错了)
- scripts/README.md 原写「Trap 19 从未存在」;改名后字面变成 TRAP-NET-19,而它是
  **真实条目**(SET_MAC 必须在 INIT_CH395 之前)→ 那句话成了假话,改用站得住的例子
- docs/编号规范.md 同一处事故叙述补准确说法:当年裸形不在册 ≠ 这个坑不存在
- 菜单页面设计.md 的「见 §8.2 陷阱 1」本就不是 TRAP-* 族的号(指本文小节第 1 条),
  改写成「见本文 §8.2 第 1 条(lv_text_get_width 的 length=0 陷阱)」

关闸第一次真拦人:咬的是自己家的审计表
- scripts/rename_maps/batch3-trap.json 里必然写着 Trap 21 / 陷阱 1 等旧形态,
  被当成 6 类「台账外新账」→ 提交被拦(拦得对,但表不是语料)
- 第 4 次同一类自循环(前三次:别名表、注册表、债务台账)→ 整个 rename_maps/
  目录入 excluded_paths;这条规律写进 §8.4:**登记号的表一律不得当引用语料**

实测变化
- 错误级 659 → 632(−27);② 空格/中文形 Trap 残余 2 处(都是上面刻意保留的)
- ③ 悬空错误 44 → 42:TRAP-GD5F-01/05/06 三处历史悬空引用自动落地为已定义
- 编号字面量 8277 → 8312(识别面没有缩水,这是改名最容易踩的坑);
  可判定比例 82.92% → 82.99%(基线 82.6%);⑦ 定义无引用 100 → 103(如 TRAP-GD5F-02
  只有定义位无人引用,如实挂 warn 不压掉)
- 台账 --prune-backlog 收掉已还清 42 条,剩 298 条(只减不增);--strict 通过

另修:core.autocrlf=true 把 SD2506_Trap_Records.md 检出成 CRLF(41 处)→ 还原 LF,
该文件 diff 只剩 1 行实质改动(仓库权威行尾是 LF,见 .gitattributes)

验证(全绿)
- @build:0 错误 0 警告(Program Size Code=213356 RO=18580 RW=1184 ZI=131480)
- ci_local.py:L0 + L0.5 全过(16 runner / 1104 断言)
- check_doc_links.py --all:143 篇文档 0 失效、0 待确认
- 改动文件字节卫生逐项与 HEAD 对比:BOM / CR / U+FFFD 异常 0

审计轨迹与文档
- 映射表 scripts/rename_maps/batch3-trap.json(含作用域切分理由与刻意不改清单)
- 别名 11 条全部带 scope;docs/编号规范.md §7.1 行状态、§8.3 批 4 行 + 说明段、
  §8.4 自循环第 4 条、变更记录
This commit is contained in:
2026-10-21 12:32:13 +08:00
parent 51604f7717
commit 52976bdec3
17 changed files with 245 additions and 288 deletions
+1 -1
View File
@@ -498,7 +498,7 @@ python tools/menu_gen/gen_menu.py
**① 框宽 w = 最宽行 + 2 条边框**(图①)
一行横向构成:`边框1 | 留白2 | 文本 |(菜单行: 间距2 + ▶10)| 留白2 | 边框1`。文本宽按字体实际步进量(`lv_text_get_width`,⚠️ 见 §8.2 陷阱 1);同框各行宽度可以不同,**框宽只由最宽的一行决定**,窄行左对齐、右侧留空:
一行横向构成:`边框1 | 留白2 | 文本 |(菜单行: 间距2 + ▶10)| 留白2 | 边框1`。文本宽按字体实际步进量(`lv_text_get_width`,⚠️ 见本文 §8.2 第 1 条(`lv_text_get_width` 的 `length=0` 陷阱));同框各行宽度可以不同,**框宽只由最宽的一行决定**,窄行左对齐、右侧留空:
w = max_行( PAD_L + 文本_w + [GAP + ▶_w] + PAD_R ) + 2×BORDER
+1 -1
View File
@@ -411,7 +411,7 @@ ECC 状态(`ECCS1:ECCS0`):`00`=无错;`01/10/11`=纠正 1/2/3 bit;`10`
| **类型** | 功能测试 |
| **标题** | 原语级块擦除(地址=块首页地址) |
| **前置条件** | SPI 已初始化 |
| **测试步骤** | `gd5f_block_erase(block)`(注意传**块编号**,内部转块首页地址,见陷阱 01) |
| **测试步骤** | `gd5f_block_erase(block)`(注意传**块编号**,内部转块首页地址,见TRAP-GD5F-01) |
| **通过标准** | 返回 `GD5F_OK`,无 `E_FAIL` |
| **覆盖原则** | `gd5f_block_erase`(TRAP-GD5F-01 修复点) |
+17 -3
View File
@@ -36,7 +36,7 @@
| **跨文档同号不同义** | `Trap 02` 在 CH395F 是"缓冲区重叠"、在 GD5F 是"测试缓冲越界";`B10` 在规划是"送检窗口"、在陷阱审计是"孤儿监听" |
| **语义进编号 → 事实一变编号就撒谎** | `P1-x` 把严重度写进号里,而审计中大量条目事后降级(`E-59` P0→P1、dhara `is_free` P1→P2):改号则引用全断,不改则号实不符 |
| **孤儿编号(代码有、文档无)** | `I-1`/`I-2`、`Task #32` 会话号、`P1-01~P1-09`、`TC-GD5F-1100/1101/1102`、`TC-STORAGE-06`、`TC-AH-*`、`TC-PE-*`(前两项项目已在 `docs/测试说明/实机测试实施指南.md` 自行承认) |
| **悬空引用(引用了不存在的号)** | `Trap 19` 从未存在却被 `docs/测试说明/CH395F_Test_Guide.md` 引用;`N-5/N-8/N-19/N-30/N-31/N-32` 销项删行后仍被引用(`N-32` = 监听生命周期模块化,被 `docs/网络/` 三篇与代码注释多处引用) |
| **悬空引用(引用了不存在的号)** | `Trap 19`(裸形;**当时的 NET 域在册表里没有这一号**——别误读成"这个坑不存在",2026-10-13 全库重排后该域确有 `TRAP-NET-19` 这条真实条目,两回事)曾被 `docs/测试说明/CH395F_Test_Guide.md` 引用;`N-5/N-8/N-19/N-30/N-31/N-32` 销项删行后仍被引用(`N-32` = 监听生命周期模块化,被 `docs/网络/` 三篇与代码注释多处引用) |
| **同一事物多种字面** | `Trap 07` / `TRAP-07` / `陷阱 1`;`gen 181` / `gen-288` / `gen68`;`TC-NET-704` / `TC704` / `TC-203` |
| **规范自身就不自洽** | `docs/测试说明/测试文档模板规范.md` §6.3 同一行并列 `TC-STORAGE-03`(2 位)与 `TC-RTC-001`(3 位);`docs/测试说明/测试文档模板规范.md` §6.2 已废止 `PHY` 模块码,而阶段 ID 至今仍是 `TM-PHY-01` |
| **机器校验只覆盖一个族** | (2026-10-15 现状,2026-10-20 已由 §8.1 收口)当时 31 个 pre-commit 钩子中只有 `TC` 有 `scripts/check_test_traceability.py`,且**未挂钩子、warn-only、正则 `TC-[A-Za-z0-9]+-\d+` 匹配不到大写后缀形态**;`E/N/S/B/C/D/A/U/O/gen/Trap` 全部裸奔 |
@@ -322,7 +322,7 @@
| `P0-x`~`P3-x` 在册项 | `DEF-*` | 严重度转列 |
| 设计说明 `D1~D10` | `DR-001`~`DR-010` | 数字对齐 |
| `B0-a/b/c`、`待确认-N` | `OQ-001`… | — |
| `Trap NN` / `陷阱 N` | `TRAP-<MOD>-<nn>` | 数字不变,补模块码 |
| `Trap NN` / `陷阱 N` | `TRAP-<MOD>-<nn>` | 数字不变,补模块码 —— **批 4 已做(2026-10-21)**:GD5F `01~07`、RTC `01`、NET `19`/`21`;`docs/硬件平台/` 属排除语料,里面的 `Trap05` 未动(见 §8.3 批 4 说明) |
| `H-1~H-7`、`L-1~L-4`、差距 `N-1~N-6` | `GAP-01`~`GAP-17` | 按文档内出现顺序 |
| 实机 `A1~A8`、看门狗 `V2/V4/V5` | `SC-01`… | — |
| 测试分层 `L0/L0.5/L1/L2/L3` | `T0/T0.5/T1/T2/T3` | 门禁 `G0~G3` 不动(两套不同尺度,不合并) |
@@ -448,6 +448,7 @@ git grep -n '<旧字面量>' # 零残留
| 批 | 日期 | 族 | 旧 → 新 | 处数 / 文件 | 别名 |
|---|---|---|---|---|---|
| **批 4(Trap)** | 2026-10-21 | 陷阱号形态 | `Trap 01~07` → `TRAP-GD5F-01~07`、`陷阱 1` → `TRAP-RTC-01`、`Trap 21`/`Trap 19` → `TRAP-NET-21`/`TRAP-NET-19`、`见陷阱 01` → `TRAP-GD5F-01` | 23 处 / 11 文件(含 `Drivers/BSP/GD5F2GQ5UE/*` 注释 4 处、`test/board/*` 2 处) | 11 条全部带 scope;映射表即审计轨迹 `scripts/rename_maps/batch3-trap.json` |
| **批 1** | 2026-10-20 | 代码规范条款 | `S1`~`S19` → `CODE-RULE-01`~`19` | 78 处 / 2 文件 | 18 条(scoped:`scripts/check_coding_standard.py`、`docs/代码规范/pre-commit使用说明.md`) |
| **批 3(口径)** | 2026-10-21 | 主机侧单测归属 | 建 9 族 `TC-HOST-*`(代码即属主)+ `subitem_ok` + `snapshot_only` + 补 README 属主 + `T-x` 入别名 | 判据与注册表改动,未改任何存量号 | 见 §8.1 口径修正记录 |
| **批 2** | 2026-10-20 | 测试用例模块码 | 16 个码 → 单词化(见 §6) | 1,146 处 / 约 30 文件 | 全局别名(字面量已完全限定,无歧义) |
@@ -457,6 +458,18 @@ git grep -n '<旧字面量>' # 零残留
---
**批 4 刻意不改的三处(写清楚,别被当成漏网)**
- `docs/环境与部署/并行任务工作树方案.md` 里的 `wip/trap22-fix` 是 **git 分支名**,不是编号——
这类「非编号字面量」要靠**类型识别**处理(与位号 `T1`、IEEE 负序 `S2`、gitlint 规则 ID 同一批),
不靠白名单硬豁免,也不许为它改分支名。
- `docs/UI设计/菜单页面设计.md` 的变更记录行「陷阱 3」按 §8.1 冻结不改写;正文里指向本文自己小节的
那处(原「见 §8.2 陷阱 1」)**本来就不是 `TRAP-*` 族的号**,已改写成
「见本文 §8.2 第 1 条(`lv_text_get_width` 的 `length=0` 陷阱)」——引用要能当问题读,
不必为两处文档内自指另立一族。
- `docs/硬件平台/` 网表分析报告里 6 处 `Trap05`(语义 = `TRAP-NET-05`)留在排除语料里不动,
盲区已登记进 `id_registry.json` 的 TRAP 族 `cursor_note`。
### 8.4 债务台账与增量拦截(2026-10-21 关闸)
**为什么不照 §8 原节奏「清零后再 `--strict`」**:存量 710 处(② 形态迁移 398 + ⑥ 裸引写全属主 269 + ③ 真悬空 44),
@@ -474,7 +487,7 @@ git grep -n '<旧字面量>' # 零残留
| 初始化 | `--write-backlog` 全量快照(关闸那次用过;之后再跑等于豁免新债,须显式确认) |
| `--only` 与 `--strict` | **互斥**(局部扫描不能当门禁结论),同时给直接返回 2 |
| 缺台账 | `--strict` 直接返回 2 并提示先生成,**绝不退化成「一次性拦死全部存量」**(那样必然逼人 `--no-verify`) |
| 台账自身不得当语料 | 关闸第一次提交就被自己的台账咬了:`id_known_backlog.json` 里必然写着 `P1-3` / `Trap 05` 这些号,扫描器当成新引用 → 报 10 类新账、提交被拦。已把台账加入 `excluded_paths`(与 `id_aliases.json` / `id_registry.json` 同一条道理:**登记号的表不是引用号的文档**) |
| 台账自身不得当语料 | 关闸第一次提交就被自己的台账咬了:`id_known_backlog.json` 里必然写着 `P1-3` / `Trap 05` 这些号,扫描器当成新引用 → 报 10 类新账、提交被拦。已把台账加入 `excluded_paths`(与 `id_aliases.json` / `id_registry.json` 同一条道理:**登记号的表不是引用号的文档**。第 4 次同样自循环:改名映射表 `scripts/rename_maps/batch3-trap.json` 里必然写着 `Trap 21` / `陷阱 1` 这些旧形态,关闸后第一次提交就被它自己拦下 6 类「新账」→ 整个 `scripts/rename_maps/` 目录一并入 `excluded_paths`(它是审计轨迹,不是引用语料) |
**关闸验收(三例,2026-10-21 实测)**:
@@ -521,6 +534,7 @@ git grep -n '<旧字面量>' # 零残留
|---|---|---|
| 2026-10-14 | 新增 P-7 与引用可读性规则 | §2 加 **P-7「编号不语义,引用必语义」**(编号本体保持无语义并冻结,但正文引用必须带语义括注、禁裸 ID 独担信息)→ 六条原则变**七条**;§5.1 加前置步"先问能不能不加号";新增 **§5.6「编号密集文档的对照节(强制)」**(≥3 个编号族必须加「导读:编号与术语」);§4.1 补登记 **`E\d+`**(N34 自愈实验编号族,已封闭)并把 `N-\d{2}` 的在册范围订正为「曾用最大 `N-33`,现存至 `N-29`」;§1.2 悬空引用示例补 `N-32`;§7.1 同步订正。起因:`docs/网络/网络自愈架构设计.md` 合并与导读节实践暴露"裸编号引用不可读",用户裁定以后尽量用语义标识 |
| (规划稿) | 建立本文档 | 全库扫描 1,385 个不同编号 / 19,306 处出现后定稿的两层编号体系(全局编号 + 文档内编号)、六条原则、目标前缀总表、三批迁移映射与 `check_ids.py` 门禁设计;用户决策:`E-xx` 冻结保留、严重度档位词 `P0~P3` 不变、文档落 `docs/编号规范.md`、阶段 1 三批全做 |
| 2026-10-21 | **批 4:陷阱号统一(② 清的第一族)** | 23 处 / 11 文件:`Trap 01~07` → `TRAP-GD5F-01~07`(属主文档 7 个标题行从此成为定义位)、`陷阱 1` → `TRAP-RTC-01`、`Trap 21`/`Trap 19` → `TRAP-NET-21`/`TRAP-NET-19`;UI 文档自指改写成平实语言。别名 11 条全部带 scope。改名后 `TRAP-GD5F-01/05/06` 三处历史悬空引用自动落地为已定义;三处刻意不改与 `docs/硬件平台/` 盲区写进 §8.3 批 4 |
| 2026-10-21 | **关闸:`id-check` 转增量拦截** | `check_ids.py` 新增 `--write-backlog` / `--prune-backlog` 与按台账比对的 `--strict`(指纹 = 文件 + 校验号 + 字面量 + 计数,**不含行号**);生成 `scripts/id_known_backlog.json`(340 条覆盖 710 处存量);钩子 `entry` 加 `--strict`。验收三例:新字面量拦、同号计数增长拦、干净态放行,全通过。新增 §8.4 说明机制与「为什么不照清零再升 strict 的原节奏」 |
| 2026-10-21 | **追溯脚本同口径对齐** | `check_test_traceability.py` 差异定义改为 DOC-ONLY / CODE-ONLY / IN-CODE 三档(真差异 45 = 38 + 7;弱保证 238 单列示数);顺带修 `TC_RE` 模块码上界 `{0,4}`→`{0,8}`——**同一个坑第二次踩**(代码侧一度从 556 缩到 217),已写进 §8.1 |
| 2026-10-21 | **B 层口径落地(批 3)** | 主机侧单测 118 号实测在代码目录外零消费者 → 建 9 族 `TC-HOST-*` 认代码为属主登记处(不逐号补文档);新增 `subitem_ok`(小写子项后缀母号在册即算已定义)、`snapshot_only`(§4.3 冻结快照族不参与定义位优先)、`allow_orphans` 旗标与 `excluded_paths` 补两项;补 `docs/任务规划/README.md` 为 `N`/`S-LDG`/`T-LDG` 属主(**我的配置漏项,曾误判 74 处真条目悬空**);`T-2`/`T-3`/`T-4`/`T-6` 入别名表标 `void`。错误级 1318 → 711(其中 504 处属口径修正、74 处属修 bug,**真正变好 0 处**)。新增 §8.1 口径修正记录表 |
+11 -11
View File
@@ -1,6 +1,6 @@
# GD5F2GQ5UE 陷阱记录
## Trap 01 — 块擦除地址错误(有效)
## TRAP-GD5F-01 — 块擦除地址错误(有效)
**发现时间**:2026-07-21
@@ -30,7 +30,7 @@
- 块擦除不使用 `block × block_size`(字节偏移),而用块首页地址
- 芯片手册的 memory mapping 必须严格遵守
## Trap 02 — 测试缓冲越界导致跨页比对误判(有效)
## TRAP-GD5F-02 — 测试缓冲越界导致跨页比对误判(有效)
**发现时间**:2026-08-26
@@ -64,7 +64,7 @@ static uint8_t s_rbuf[GD5F_PAGE_SIZE * 2];
- 任何“跨页 / 大于单页”的读写测试,缓冲必须按**实际长度上限**而非单页大小分配
- 越界写会污染相邻全局变量,可能引起其它用例莫名失败,定位时优先怀疑缓冲尺寸
## Trap 03 — 驱动读写擦缺越界检查(有效 / 健壮性缺口)
## TRAP-GD5F-03 — 驱动读写擦缺越界检查(有效 / 健壮性缺口)
**发现时间**:2026-08-26
@@ -90,19 +90,19 @@ if (offset < 0 || (unsigned long)offset + size > (unsigned long)GD5F_TOTAL_SIZE)
**验证结果**:
- TC-GD5F-1001 read/write 越界均被拒绝(ret=-1),测试 PASS
- TC-GD5F-1002 size=0 仍返回 `GD5F_OK`(offset 合法且 size=0 不越界),符合预期
- 该检查还顺带逮到 Trap 04 的测试越界擦除(见下)
- 该检查还顺带逮到 TRAP-GD5F-04 的测试越界擦除(见下)
**经验教训**:
- 面向字节偏移的裸 NAND 接口必须做容量边界检查,调用方传错参数时尽早失败
- 无越界检查的驱动容易“静默回绕”,问题极难定位
## Trap 04 — gd5f_find_run 返回语义与多块擦除窗口错位(测试 bug)
## TRAP-GD5F-04 — gd5f_find_run 返回语义与多块擦除窗口错位(测试 bug)
**发现时间**:2026-08-26
**现象**:
TC-GD5F-402 多块擦除(`gd5f_find_run(3)` 后擦 3 块)返回 `ret=-1`。
经 Trap 03 的边界检查定位:实际要擦的块超出了设备末尾。
经 TRAP-GD5F-03 的边界检查定位:实际要擦的块超出了设备末尾。
**根因**:
`gd5f_find_run(n)` 原实现返回的是**连续好块的末尾块号** `top`
@@ -133,7 +133,7 @@ if (ok) {
调用方与实现必须一致
- 这类错位 bug 往往只在“区间贴到设备边界”时才触发,正常情况能过,建议测试覆盖边界块
## Trap 05 — FatFs 探针文件名非法 → 无限重格式化(已修复,2026-09-20)
## TRAP-GD5F-05 — FatFs 探针文件名非法 → 无限重格式化(已修复,2026-09-20)
**发现时间**:2026-09-20(症状自卷健康探针引入之日起长期存在)
@@ -197,7 +197,7 @@ if (ok) {
- 探针自身也可能有 bug:错误码要记录"是哪次调用返回的 + 枚举语义"——
本例 fr=6 在日志里挂了几十个 boot 没人查过枚举表
## Trap 06 — 轮询路径"伪完成":HAL 失败被伪装成操作完成(已修复,2026-10-03)
## TRAP-GD5F-06 — 轮询路径"伪完成":HAL 失败被伪装成操作完成(已修复,2026-10-03)
**发现时间**:2026-10-03(错误码传播审计 E-10/E-42/E-53/E-54/E-56/E-57 复核 + 台架套件回归)
@@ -232,7 +232,7 @@ if (ok) {
保护既有好副本比刷新更重要;
- 使能类配置(ECC)必须**回读校验**,不能只信写命令的返回。
## Trap 07 — dhara 移植层:`is_free` 只看页首 + HAL 无几何校验(已修复,2026-10-15)
## TRAP-GD5F-07 — dhara 移植层:`is_free` 只看页首 + HAL 无几何校验(已修复,2026-10-15)
**发现时间**:2026-10-15(`项目审查与优化建议报告.md` N-12 / N-13 复核,登记簿原 N-21)
@@ -249,7 +249,7 @@ if (ok) {
加完 `FTL_START_BLOCK` 偏移送进 SPI 命令后,被芯片地址位**截断成某个真实页**
→ 静默读写、甚至把无辜页的数据 GC 搬走。
**与 Trap 03 的关系(本条的核心教训)**:Trap 03 已为**裸驱动字节偏移 API**
**与 TRAP-GD5F-03 的关系(本条的核心教训)**:TRAP-GD5F-03 已为**裸驱动字节偏移 API**
(`gd5f2gq5ue_read/write/erase`)补过容量检查,但**dhara 移植层是另一个入口**,同一教训在那儿
原样重演。边界校验必须**逐层**做——"下层查过了"推不出"上层调用也安全",何况本例下层查的是
字节偏移、上层传的是页号,两者根本不是同一个量。
@@ -267,7 +267,7 @@ if (ok) {
- 无错误通道的两个函数取**保守值**:`is_free` 越界返回 0(判非空,最多少用一页)、
`is_bad` 越界返回 1(判坏,绝不读写)、`mark_bad` 越界直接返回(绝不标无辜好块)。
- `is_free` 内 `gd5f_page_read` / `gd5f_read_from_cache` 任一失败 → 返回 0
(Trap 06 同族:读失败**不得**伪装成"空闲")。
(TRAP-GD5F-06 同族:读失败**不得**伪装成"空闲")。
**验证**:
+1 -1
View File
@@ -1,6 +1,6 @@
# SD2506API-G 陷阱记录 (Trap Records)
## 陷阱 1:KEIL/ARMCC 下十六进制字面量 `H` 后缀被编译为 0(严重)
## TRAP-RTC-01:KEIL/ARMCC 下十六进制字面量 `H` 后缀被编译为 0(严重)
### 现象
SD2506 RTC 时间写不进去:`sd2506_set_time()` 返回 OK,但回读 / 示波器 / 重启后时间不更新。
@@ -25,7 +25,7 @@
|------|------|-----------|-----------------|
| 项目结构 | **A−** | 六层分层真实可执行、命名一致、门禁到位;反向依赖控制在 4 处 | `NETCFG`/`UI` 语义层错位(S-1)、4 处裸 `extern`(S-2)、`rs485_task.c` 仍在注册白名单里等 B2 |
| 文档分布 | **A−** | 工程文档 **87 篇 / 30,781 行**(2026-10-15 随 `错误码传播审计.md` 删除而 −1 篇 / −635 行),`docs/README.md` 索引 + `docs/文档规范.md` + 三档一致性门禁全部落地,`check_doc_links --all` = 0 失效 | **D-1**:`docs/` 占仓库 **71.8%**、手册图片 **36.3 MB**、`.git` 已 **235 MB**(已决策暂不处理,登记观察) |
| 模块设计 | **A−** | 看门狗(IWDG + 心跳位图 + 4 个 Fault 现场 + `.noinit`)、就绪屏障、卷锁、FTP 鉴权、`Error_Handler` 自恢复、ADC 全链均已落地;**原列的 dhara 移植层两处缺陷(N-12/N-13)与日志逐条开关(N-16)已于 2026-10-15 修复** → `GD5F2GQ5UE_Trap_Records.md` Trap 07、`../架构设计/STM32F4-Base存储架构说明.md` §5.3、`../子系统设计/运行与自检记录设计说明.md` §4.4/§4.5 | 驱动层无统一错误码约定(S-5)、RS485 无协议栈(随 B2 暂缓) |
| 模块设计 | **A−** | 看门狗(IWDG + 心跳位图 + 4 个 Fault 现场 + `.noinit`)、就绪屏障、卷锁、FTP 鉴权、`Error_Handler` 自恢复、ADC 全链均已落地;**原列的 dhara 移植层两处缺陷(N-12/N-13)与日志逐条开关(N-16)已于 2026-10-15 修复** → `GD5F2GQ5UE_Trap_Records.md` TRAP-GD5F-07、`../架构设计/STM32F4-Base存储架构说明.md` §5.3、`../子系统设计/运行与自检记录设计说明.md` §4.4/§4.5 | 驱动层无统一错误码约定(S-5)、RS485 无协议栈(随 B2 暂缓) |
| 内存使用 | **B+** | 堆迁 CCM + 栈/堆三面观测常开 + `mem-budget` 92% 门禁 + 预算台账与趋势基线;**R-9 已落地(2026-10-15)→ SRAM1 由 74.9% 降到 56.1%;同日移植层与日志修复 +1.6 KB → 现 **57.4%(余 55,840 B)**,不再是卡点** | **内存优化簇已整簇暂缓**(用户裁定 2026-10-15):R-2 后半(待迁 29,570 B → CCM,只差缩堆 56→32 KB)与 R-3 / R-4 / R-6 不再排期,理由与重开条件见 §5.3;**当前真正的约束是 CCM 只剩 7,904 B**——加任务 / 抬栈 / 加堆会先在这里撞墙,届时按 §5.3 重开;MicroLIB 512 B C 堆仍无机械检查(§5.5) |
| Flash 使用 | **A−** | F-1/F-2/F-3 落地省 64,576 B → 占用 **22.2%(232,280 B)** | F-4/F-5/F-6 ≈10 KB + 编译时长(§5.4) |
| UI 标准化 | **B+** | W6 第一波已落地(2026-10-15):**L0 设计令牌层** `ui_tokens.h` 建成、**L2 页面注册表** `ui_page_registry.{c,h}` 由生成器产出并**删除了手写 `case` 分发**、`font-charset` 钩子 + `registration-check` 第 ④ 类接线校验上线、字体子集瘦身 −80 B | L1 组件库已起步(U2 首个 `ui_w_records`,2026-10-20),但仅此 1 个组件、**目标页未落地**(现存 7 个 `ui_page_*.c`)、**golden 像素回归已于 2026-10-20 挂入提交门禁**(`ui-golden`)、`ui_w_form` 推迟 U5(§6) |