511fd30cc6
用户裁定:文档只写现状,历史流水一律删掉,过程查 git log。 - 43 篇「变更记录 / 修订记录」整节删除:继电保护规划 12.6 KB、产品 需求 11.8 KB、项目部署环境 5.5 KB、BSD Socket 指南 5.3 KB、架构 总览 5.0 KB、实机测试实施指南 3.8 KB 等 - 23 篇别处仍有指向:只留节名 + 一行「本文件不再记流水账,过程查 git log」,节号与锚点不位移(doc-links 不因此断链) - 5 篇整表保留(被当唯一证据 / 活台账引用):看门狗设计说明、配置 文件设计说明、RAM预算台账、内容页架构、本地工具路径环境变量方案 - 规范同步:文档规范 §5.1 改新裁定;测试文档模板规范删示例节与 登记句;测试开发标准流程 / UI 两篇 / 实机测试实施指南 / 四篇单测 说明 / 并行任务工作树方案 / 编号规范 的「登记变更记录」改「写进 正文」 - 技能同步:stale-doc-count-sweep / ui-verify / id-family 三个 SKILL 正文不再要求追加流水行(顺带消掉 SKILL.md:121「产品需求 §12」 失效引用) - 修 5 处悬空指针:采样有效性校验目录锚点、BSD 指南「文末变更 记录」、docs/README 过期描述、网络自愈架构两处指向面 72 篇文档净减 600 余行;check_doc_links --all --sections-strict 可判 定比例 61% → 78%、失效引用 0;静态门禁 passed=50 failed=0;gitlint 10 条历史提交信息 0 failed。 未提交他人在飞改动:.dsh/skills/keil-build/*(%SystemDrive% 守卫)。
4.9 KiB
4.9 KiB
registration-check — 双端注册反向校验(源文件有没有真的参与编译)
一句话:本仓两处注册表都是显式文件列表,忘了登记的文件能编过、能提交,但从不参与编译 ——这一门专抓"写了却从不生效"的死代码,包括第四种更隐蔽的:页面描述符没接线。
- 配置:
entry: python scripts/check_registration.py --strict、pass_filenames: false。 - 背景:登记簿条目「rs485_task 白名单缺口」;UI 页面那类是「UI 字符集与像素回归门禁」补强(2026-10-15)。
1. 它在查什么(四类缺口)
扫描 App/、Drivers/BSP/、Src/ 下全部 .c(排除第三方),对照 MDK-ARM/STM32F407-Demo.uvprojx 的 <FilePath> 与 simulator/CMakeLists.txt 的源列表:
| 类 | 情形 | 后果 |
|---|---|---|
| ① | 文件存在但未进 uvprojx | 固件端不编译(死代码或漏注册) |
| ② | 文件存在但未进 CMakeLists | 模拟器端不编译——MCU-only 文件不进模拟器是正确的,脚本按豁免判定 |
| ③ | 注册了但文件不存在(反向) | 幽灵注册(改名/删除后残留条目) |
| ④ | Drivers/BSP/UI/ui_page_*.c 定义了 ui_page_<name>_desc,但该符号在 UI 目录内除自身 .c/.h 外无人引用 |
页面没接进 ui_content_page.c 的 s_defs[] 描述符表:两端编译链接全过(无人引用的 desc 被链接器整段剥离),菜单永远打不开这一页 |
- UI 页面的"注册"有两层,第 ④ 类只管第二层:第一层是构建注册(uvprojx + CMakeLists,
即 ①② 类);第二层是框架注册(
ui_content_page.h的枚举 +ui_content_page.c的s_defs[]描述符表)。只做第一层 → 编译链接全过,但菜单里就是没有这一页。
2. 为什么要它
- 真事故:
App/task/rs485_task.c、Drivers/BSP/NET/lftpd/lftpd_log.c历史上两处都没注册, 等于代码从不参与任何一端编译,而读者以为功能已生效。 - 第 ④ 类尤其值:2026-10-15 实测,前三类对"页面写了但没接线"完全照不出(编译链接都过), 所以才有"新增 UI 页面必须过本门"的机械口径。
3. 触发面
files: 覆盖 \.c$|\.uvprojx$|CMakeLists\.txt$|^scripts/check_registration\.py$;
pass_filenames: false → 每次全量对照两份注册表。
4. 报错怎么读
双端注册反向校验 (uvprojx + CMakeLists).......Failed
[示例] [GAP-1] App/x/y.c 未出现在 MDK-ARM/STM32F407-Demo.uvprojx
- 单独跑:
& '.venv\Scripts\python.exe' scripts/check_registration.py --strict。 - 修法是补注册(新
.c走new-source-fileskill 的两处登记),不是把文件删掉凑绿。 - 新目录还要把目录加进
uvprojx的<IncludePath>,否则报错会落在消费者编译单元上 (cannot open source input file),容易被误判成别人的问题。
5. 好处
- 把"显式列表 = 必须登记两次"这条极易忘的约定机械化;
- 反向校验(③)让改名/删文件不留幽灵条目,配合
scripts/rename_ref.py才敢说"改名安全"。
6. 限制与盲区
- 只管"在不在列表里",不管"注册得对不对":把
a.c的<FilePath>指向b.c,只要路径 存在就过。 - MCU-only / 模拟器专用的判定靠豁免清单(脚本内
KNOWN_GAPS一类,存量 + 逐条理由)。 新增一个正确的 MCU-only 文件需要同时改豁免清单,否则②会误报——反过来也成立:进了豁免 清单的文件就永久不再被检查。 - 第 ④ 类只覆盖
ui_page_*.c+ui_page_<name>_desc这一种接线形态;其它"注册了但运行期 无人调用"的入口(命令表、事件回调)不在内。 - 头文件不校验:只漏
.h不会报(漏的是 include 路径,不是注册表)。 - 它不看条件编译:文件在列表里但整个文件被
#ifdef关掉,仍然算"已注册"。
7. 豁免与基线
-
无"只减不增"的基线,而是逐条带理由的已知缺口清单(
KNOWN_GAPS形态):新增条目必须写 理由,性质上比基线更容易被滥用,改动时要看得到理由文本。 -
豁免用显式清单 + 每行理由(命名模式
*_mcu.c加个别点名),不整目录一刀切——一刀切等于 把该目录所有漏注册都免了。 -
存量缺口走白名单只打
[WARN]不拦:KNOWN_GAPS里登记着App/task/rs485_task.c、Drivers/BSP/NET/lftpd/lftpd_log.c(Lead 处置中)。
8. 改这个门禁本身
- 加新的注册面(例如新增一套第三方构建脚本)要同步"正向 + 反向"两向检查,只查单向会漏幽灵注册;
- 放宽第 ② 类(更多豁免)前,先确认该文件真的不需要在 PC 上跑——模拟器不编译意味着该文件的
逻辑永远没有主机侧单测(见
host-unit-tests)。