本批是 ② 形态迁移清的第一族(用户裁定顺序:② 里的 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 条、变更记录
57 KiB
编号规范
适用对象:本仓库全部 Markdown 文档、C/Python/脚本源码注释、提交信息中出现的实体编号(
E-44、N-21、TC-NET-601、FR-STO-1、Trap 07这类"字母 + 数字"的条目身份标识)。 不适用:C 语言标识符(g_/s_/PS_*/TEST_SUITE_*)、元器件位号(U1/C12/R3)、章节号(§3.2,归docs/文档规范.md§3.5 管)——见下文「划界」一节。 强制程度:§2~§5 为强制(由scripts/check_ids.py机械校验,§8 已落地 warn-only);§6~§10 为约定 + 迁移计划。 相关文档:docs/文档规范.md(链接/章节/门禁总规范)、docs/任务规划/README.md§0(本规范的登记簿摘要)、docs/测试说明/测试文档模板规范.md§6(测试侧编号细则)、docs/代码规范/pre-commit使用说明.md§2.25(id-check钩子)。 状态:§8 门禁已落地(warn-only,含scripts/id_registry.json/scripts/id_aliases.json,实测基线见 §8.1);§4 的目标前缀与 §7 的迁移映射在阶段 1 落地前尚未生效,落地进度见 §9。
1. 为什么要重写编号体系
1.1 病根:前缀按"来源"分配,不按"事物类别"分配
每来一次审计/复审/专项,就自造一套前缀,字母很快瓜分殆尽:
| 来源 | 自造的前缀 |
|---|---|
| 2026-09-21 错误码传播审计 | E-xx、缺陷模式 P1~P9、严重度 P0~P2 |
| 2026-09-15/09-21 代码审计 | P0-x ~ P3-x(严重度直接进编号) |
| 2026-09 项目审查与优化建议报告 | N-xx、D-x、S-x、R-x、F-x、U1~U5 |
| 台架与长期观察 | N-x、S-x、T-x、gen、round、V2/V4/V5 |
| 2026-10-02 复审 | S1~S14、A-1~A-7 |
| 任务规划 | W<n>、B\d、C\d、D\d、M\d |
| 各模块陷阱/设计文档 | Trap NN、陷阱 N、D1~D10、O1~O6、U1~U15、①~④ |
后果:同一字母被 3~5 个来源共用,编号本身不再能定位事物。
1.2 已确证的事故(全部有仓内证据,非假想)
| 类型 | 实锤 |
|---|---|
| 同字母多义 | P1 五义(缺陷模式 / 严重度 / 审计条目 P1-8 / 用例优先级 / ch395f_test_task.c 的 Phase1 测试项 P1-01);L1 四义(算法层 / 测试分层 / UI 四层 / CubeMX 三层);U1 四义;O4 四篇文档四义 |
| 同一文件内双义 | 实机测试实施指南.md 的 A2/A3/A4 既是环境预检项(§2)又是已完成事项(§10) |
| 连字符/补零偷偷承载语义 | R1=风险、R-2=内存优化项;D7=验证窗口、D-7=文档门禁、D1~D7=设计决策;N-2(登记簿)与 N-02(报告)同号不同义 |
| 跨文档同号不同义 | 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(裸形;当时的 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 全部裸奔 |
可借鉴的先例:
§N.M章节引用当年 1,578 处也全靠自觉,靠「紧邻写法 + 别名表 + 可判定比例 + 钩子」把可判定比例做到 58% 并转为拦提交(docs/文档规范.md§3.5)。编号走同一条路径即可收口。
2. 八条设计原则(强制)
| # | 原则 | 理由 |
|---|---|---|
| P-1 | 前缀 = 事物类别,不是来源文档/审计轮次。来源是登记簿的「出处」列,不进编号 | 否则每轮审计都造一套新字母,必然瓜分殆尽 |
| P-2 | 编号不携带语义:严重度、状态、日期、负责人、波次一律是表格列 | 降级只改列,编号永不变、引用永不断(P1-x 的历史教训) |
| P-3 | 一个前缀只有一个属主登记处;前缀一经分配永不复用给别类,号段用尽即扩位(N-99→N-100),绝不换字母 |
保证"看到前缀就知道去哪张表查" |
| P-4 | 形态唯一:<前缀>-<序号>;前缀 1~3 位大写字母;序号位数按类别固定并左补零;子项只允许一级 -<小写字母>。禁止裸形(S3)、空格形(Trap 07)、中文形(陷阱 1)、圈号(①②③④) |
连字符与补零不得承载语义;字面唯一才能被机器判定 |
| P-5 | 只增不复用;每个类别有「下一个可用号」游标(scripts/id_registry.json,§8.1 已落地),新增先取游标 |
并行任务与多文档同时新增时防撞号(《项目审查与优化建议报告》与登记簿并轨时 N-16 撞过号,就是没有游标——见 docs/任务规划/README.md §0) |
| P-6 | 引用必须机器可判定:跨文档引用用行内代码,首次出现紧邻属主文档名;文档内编号必须带文档名 | 与 §N.M 同一条路:能校验的约定才算存在 |
| P-7 | 编号不语义,引用必语义:编号本体保持无语义并冻结(同 P-2);但正文引用必须带语义括注——TRAP-NET-18(异常释放后排空 RX 残渣)、docs/网络/网络自愈架构设计.md §4.6(应用主动拆会话保监听);禁止裸 ID 单独承担信息。语义放括注,事实变了只改括注、编号不变 |
读者不该为看懂一句话去跳三篇文档。可读性由引用方式解决,不由编号命名解决——命名带语义会重蹈 P1-x 覆辙(§1.2)。落地见 §5.6 |
| P-8 | 语义优先:规划 / 待办类条目优先用语义标识(§3.3)——一行短语即标识,不分配字母+数字号;只有需机器解析或作历史证词的类别才发编号,且引用时强制带语义括注(P-7) | 编号的唯一性维护成本已实测超过收益:N-31 销项删行后按"现存最大值 +1"又被取走,与两处历史引用撞号(docs/任务规划/README.md §0)。短语自带唯一性(重名一眼可见),且读者不必跳表查号 |
3. 主轴:编号 / 语义标识 / 章节引用
| 层 | 适用事物 | 形态 | 引用规则 | 门禁校验 |
|---|---|---|---|---|
| 全局编号 | 会跨文档流转:需求、缺陷、待办、决策、风险、测试用例、陷阱记录 | 全局唯一前缀 + 全局序号 + 唯一属主登记处 | 行内代码;跨文档首次出现紧邻属主名 | 全库唯一;必须能在属主表查到定义行 |
| 文档内编号 | 只在定义它的那篇文档内有意义:状态机组合、方案档位、专项风险、专项阶段 | 允许存在,前缀带类别码,号段文档内独立 | 必须紧邻文档名(同 §N.M 紧邻规则) |
校验"该文档内确有此编号" |
| 语义标识(§3.3,规划 / 待办类默认) | 登记簿条目、任务卡、待确认、风险、决策、缺陷、工作项、差距、验证场景 | 一行短语即标识,不分配字母+数字号;≤20 汉字 | 同文档内写短语;跨文档紧邻属主文档名 | 同表内去重(同义异写算撞名);引用查不到 = 悬空 |
3.1 判定口诀
会不会在别的文档里被引用?会 → 全局编号;不会 → 文档内编号,且引用必须带文档名。
前置一步(P-8):规划 / 待办类条目先问"能不能用一行短语说清是什么事"—— 能 → 用语义标识(§3.3),不发编号;只有需机器解析(
TC)或作历史证词(TRAP)才进上面的判定。
现状的病根正是把该全局的(发现、待办)做成了文档内编号(各文档自造 O1~O4、A1~A6),又把该文档内的(设计决策 D1~D7、状态机 U1~U15)做成了裸形全局编号。
3.2 编号 vs 章节引用
| 条目特征 | 用什么 |
|---|---|
| 会增删、会重排、只是"读第几条" | 章节引用 `docs/xxx.md` §N.M(不造编号) |
| 需要稳定身份(要销项、要被代码引用、要跨文档追溯) | 编号 |
各设计文档的"本期不做 / 遗留可选项"清单(现状 O1~O4 四篇文档四义)默认不造编号,改用 §小节引用;确需逐条引用时才启用文档内编号 OOS-<nn>。
3.3 语义标识(新条目默认形态)
立场:编号是"确需跨文档长期引用"才付的成本(§5.1 第 0 步)。规划与待办类条目 生命周期短、销项即删行,编号带来的唯一性维护成本已实测超过收益——
N-31销项删行后 按"现存最大值 +1"又被取走,与两处历史引用撞号(详见docs/任务规划/README.md§0)。 这类条目改用语义标识:一行短语本身就是标识,不再分配字母+数字号。(原则见 P-8)
形态规则(强制):
| 项 | 规则 |
|---|---|
| 构成 | 主语 + 症状/动作,直接说清是什么事:49s 日志静默、USART1 TX-only 根治、dhara is_free/copy 判据 |
| 长度 | ≤20 个汉字(或 ≤40 个 ASCII 字符),一行写完 |
| 禁用 | 不含 |(表格安全)、不换行、不以 - 结尾、不带序号后缀(日志静默-1 非法) |
| 不含易变属性 | 严重度、状态、日期、负责人、波次一律写进表格列,不进标识(同 P-2) |
| 唯一性 | 同一属主登记处内唯一;同义异写视为撞名(日志静默 与 49s 日志静默 只能留一条) |
| 冻结 | 措辞一经登记即冻结;确需改写在原行加"别名"列,旧措辞保留可查(§5.7) |
适用分界(强制):
| 域 | 条目 | 标识形态 |
|---|---|---|
| 规划 / 待办(转语义) | 登记簿条目(原 N-x / S-x / T-x)、排期任务卡(原 B / C / D)、待确认(OQ)、风险(RSK)、决策(DR)、缺陷(DEF)、工作项(WI)、模拟器差距(GAP)、验证场景(SC) |
语义标识 |
| 机器解析 / 历史证词(保留编号) | TC-*、TRAP-*、FR-* / NFR-*、RC-* |
编号 + 强制语义括注(P-7) |
| 历史冻结族(§4.3) | E-xx、报告自有编号、S1~S14、A-1~A-7、P0-x~P3-x |
不回改,走别名表 |
⚠ 为什么
TC-*不能转语义(硬约束,勿试):scripts/check_test_traceability.py用TC-[A-Z]{1,4}-\d{3,4}做可追溯性比对;test/host/ch395f_socket_test.py把TC-NET-602打进运行日志;板级test/board/ch395f_test_task.c直接把它编进 C 宏名PHASE2_TC203_TIMEOUT_MS。语义短语进不了宏名,也做不了正则排序。TRAP-*同理不转:196 处文档 + 122 处代码引用,是历史证词的高频锚点。
引用写法:
| 场景 | 写法 |
|---|---|
| 登记处表内 | `49s 日志静默`(# 列填短语本身,不再填号) |
| 跨文档 | `docs/任务规划/登记簿.md` 的 `49s 日志静默`(紧邻文档名,同 §N.M 规则) |
| 代码注释 | 允许,但必须带属主文档名(同 §5.3),如:(登记簿 8 路电气量分属两片转换器) |
| 销项 | 删行 + 清全库引用;短语不复用(同"号不回收",见 §5.7) |
4. 编号空间总表
4.1 在册保留(零改写,仅补规则)
| 前缀(正则) | 类别 | 属主登记处 | 游标/规则 |
|---|---|---|---|
FR-[A-Z0-9]+-\d{2} |
功能需求 | docs/产品需求/产品需求设计文档.md §5 |
各域独立递增;新增域写进该文 §1.2 术语与缩写 |
NFR-[A-Z0-9]+-\d{2} |
非功能需求(新建,现 §7 全是散文无号) | docs/产品需求/产品需求设计文档.md §7 |
从 NFR-<域>-01 起 |
N-\d{1,3}[a-z]? |
登记簿条目(技术债 / 长期观察 / 硬件改版项;含义由"网络项"重定义) | docs/任务规划/登记簿.md |
曾用最大 N-33(N-30~N-33 均已销项、登记簿行已删,现存至 N-29)→ 游标 N-34(号不回收);原 S-x/T-x 并入本族(§7.1)。⚠ 实测另有报告侧补零带子项后缀的 N-03a/N-03c 与 §5.5 的扩位示例 N-100 → 位数收到 3、允许小写子项后缀 |
E-\d{1,2} |
错误码/返回值传播审计发现 | 无(原属主 docs/问题记录/错误码传播审计.md 已于 2026-10-15 删除) |
冻结:E-63 为最大号,不再新增;新发现一律 DEF;现存引用仅作历史指称(§4.3)。⚠ 属主已删 → 该族无法判定义存在与否,门禁只拦越游标(§8.1) |
E\d+ |
自愈实验编号(N34 台架实验,无连字符) | docs/网络/网络自愈架构设计.md §5.2 |
⚠ 规范原记「已封闭 E0E15」,实测该表已到 E19(E16E19 收录,封闭线待订。⚠ 与上一行靠连字符区分:带连字符 = 审计发现 |
TC-[A-Z][A-Z0-9]{0,4}-\d{1,4}[a-z]? |
测试用例 | 各测试文档 | 3 位起;分阶段套件序号 = 阶段号×100 + 项号(阶段 ≥10 自然进位 4 位,TC-NET-1001 合规);后缀只允许 -<小写字母>。⚠ 模块码 GD5F/I104 含数字,规范原写的 [A-Z]{1,4} 会整族漏掉 GD5F(实测 285 处)→ 已按实测放宽 |
F-<MOD>-<nn> |
net / 驱动侧功能与改进项(F-NET-2~17、F-DRV-*、F-MS-*) |
docs/网络/网络自愈架构设计.md |
2026-10-20 补行:本族早就在被代码注释大量引用(实测 60+ 处)而总表里没有——正是 §5.1 第 1 步"表里没有的类别先改本规范"的适用对象;id-check 落地时按实测收编 |
P-<n> |
本规范的设计原则条目(P-1~P-8) |
本文档 §2 | 2026-10-20 补行;⚠ 与档位词 P0~P3(§4.4)、审计条目 P0-x(§4.3)靠连字符区分,三者形态互斥 |
CODE-RULE-<nn> |
嵌入式 C 代码规范条款号(配原文章节号,如 CODE-RULE-03 (3.4.1)) |
scripts/check_coding_standard.py(规则表 = 单一事实源) |
2026-10-20 批 1 新建:原名是裸形 S1~S19,与登记簿 S-x、UI 像素状态、2026-10-02 复审专项条目四义撞形(§1.2)→ 单词化改名,旧号进 id_aliases.json 的 scoped 条目。⚠ S14 历史上不存在,空洞不复用 → 游标 19 |
MENU-STATE-<nn> |
UI 菜单像素回归状态号(按键序列状态,共 8 态) | simulator/tests/check_menu_rows.py 的 STATES 表 |
2026-10-20 批 1 新建:原名裸形 S0~S7(同上撞形);冻结在 07,加状态须先改本族游标 |
TM-[A-Z]{1,4}-\d{2} |
测试阶段 | 各测试文档 | 模块码取 §6 统一表(TM-PHY-01 → TM-NET-01) |
DP-[A-Z]{1,4}-\d{2} |
设计原则 | 各测试文档 | 加模块码(现 DP-01 跨文档会撞) |
L\d / L\d-\d{1,2} |
采集与保护分层、层内条目 | docs/算法/继电保护功能复现规划.md §3 |
保留(代码侧 141 处引用,是全项目最规范的一族,作样板);L 前缀专属此族 |
W\d+ |
波次 | docs/任务规划/README.md §2.0 |
保留;游标 W8;子任务卡不再用 W1-0 形态(并入 WI) |
4.2 目标前缀(阶段 1 改名后启用)
2026-10-15 修订(依 P-8 / §3.3):本表中规划 / 待办类前缀在阶段 1 落地时改为 语义标识形态(不再分配序号)——
DEF/WI/OQ/RSK/DR/MS/GAP/SC; 需机器解析或作历史证词的保留编号——TC/TM/DP/TRAP/FR/NFR/RC/GEN/RUN,引用时强制带语义括注(P-7)。下表的"游标"列对转语义的前缀不再适用。
| 新前缀 | 类别 | 收编的旧编号 | 新属主登记处 | 游标 |
|---|---|---|---|---|
DEF-<nnn> |
缺陷 / 问题发现 | P0-x~P3-x(在册项)、新发现 |
[计划] docs/问题记录/缺陷登记簿.md |
DEF-001 |
WI-<nnn> |
工作项 / 任务卡 | B\d(功能主线)、C\d(结构债)、D\d(验证窗口)、W1-0、S1~S14、A-1~A-7、P1-10、报告 R-x(内存优化)、F-x、U1~U5 的未闭环项 |
docs/任务规划/ 波次与排期文件(类别做列) |
WI-001 |
DR-<nnn> |
决策记录 | docs/网络/网络自愈架构设计.md 的 D1~D7 |
[计划] docs/架构设计/决策记录登记簿.md |
DR-001 |
OQ-<nnn> |
待确认 / 开放问题 | B0-a/b/c、待确认-N |
docs/任务规划/基线与待确认.md |
OQ-001 |
RSK-<nn> |
风险(文档内编号) | 保护规划 R1~R8、看门狗 R1~R7 |
各文档风险表(引用必须带文档名) | 各文档自 RSK-01 |
TRAP-<MOD>-<nn> |
陷阱记录 | Trap 07、TRAP-07、陷阱 1 |
docs/问题记录/<模块>_Trap_Records.md |
保留原号(TRAP-NET-01~21——NET 域 2026-10-13 全库迁移并重排连续,沿革见该文档、TRAP-GD5F-01~06、TRAP-RTC-01~) |
GAP-<nn> |
模拟器差距 | H-1~H-7、L-1~L-4、差距清单 N-1~N-6 |
docs/测试说明/模拟器差距清单.md |
GAP-01 |
SC-<nn> |
实机验证场景 | 实机预检 A1~A8、看门狗验证用例 V2/V4/V5 |
docs/测试说明/实机测试实施指南.md |
SC-01 |
T0/T0.5/T1/T2/T3 |
测试分层(原 L0/L0.5/L1/L2/L3) |
测试分层五档 | docs/测试说明/测试开发标准流程.md §1 |
固定五档 |
G0/G0.5/G1/G2/G3 |
门禁(必跑清单,与测试分层是两套,不合并) | 现门禁决策表 G0~G3 |
docs/测试说明/测试开发标准流程.md §1.1 |
固定 |
GEN-<nnn> |
台架日志代次 | gen 181、gen-288、gen68 |
docs/测试说明/串口助手设计说明.md |
数字不变,仅改字面 |
RUN-<yyyymmdd>-<n> |
台架轮次 | round 1~9 |
docs/测试说明/实机测试实施指南.md |
日期制 |
MS-<nn> |
里程碑 | M1~M3 |
波次文件 | MS-01 |
RC-<nn> |
net 周期对账类型 | ①②③④⑤(唯一被代码逻辑引用的圈号链) |
docs/网络/网络自愈架构设计.md |
RC-01~RC-05 |
PAT-<nn> |
缺陷模式(九类) | 原 docs/问题记录/错误码传播审计.md §1.1 的 P1~P9(该文档已删除,定义迁至本文档 §4.2.1) |
本文档 §4.2.1 | PAT-01~PAT-09 |
ST-<n> |
专项内部实施阶段(文档内编号) | 保护规划 §7.1 的 P0~P5、方案阶段 P0~P3 |
各专项文档 | 各文档自 ST-0 |
UL-<n> |
UI 标准化四层(文档内编号) | 报告 UI 四层 L0~L3 |
docs/UI设计/UI_设计架构.md |
UL-0 |
LAT-<nn> |
链路延迟分段(文档内编号) | docs/测试说明/链路延迟测试说明.md 的 L1~L11 |
同文 | LAT-01 |
CS-<n> |
CubeMX 定制存活三层 | AGENTS.md 的 L1 写进 .ioc → L2 USER CODE → L3 审计 |
docs/子系统设计/看门狗设计说明.md §10 |
CS-1~CS-3 |
4.2.1 缺陷模式定义(PAT-01~PAT-09)
2026-10-15 由已删除的 docs/问题记录/错误码传播审计.md §1.1 迁入(原编号 P1~P9,与发现编号 E-xx 区分)。
新发现归入 DEF-<nnn> 时,"缺陷模式"列仍按本表取值:
| 模式 | 名字 | 一句话 | 典型症状 |
|---|---|---|---|
| PAT-01 | 值拷贝队列陷阱 | 消息体按值拷进队列,netTask 修改的是副本,调用方看不到 | 回传字段恒为初始值 |
| PAT-02 | 共享全局错误变量竞态 | 全局 errno 被多任务交错覆写 |
报出别人的错误码 |
| PAT-03 | 返回值与错误码混同 | "0 = 成功"其实是"命令已发出";成功路径不清 errno | 失败被当成功 |
| PAT-04 | 返回值未检查 | HAL_* / 库函数返回被丢弃 |
失败静默继续 |
| PAT-05 | 事件标志语义 | 状态位被当作命令位消费掉 | 等待者永不唤醒 |
| PAT-06 | 通知值宽度与符号 | 32 位通知值装不下 / 符号位被当成数据 | 大长度变负数 |
| PAT-07 | ISR 与跨上下文共享状态 | ISR 写、任务读,无同步 | 读到半包 / 撕裂 |
| PAT-08 | 外设 / 库特定约定 | 该外设 / 该移植版特有的规则 | 照抄上游示例即错 |
| PAT-09 | 超时与错误混同 | 超时用同一个码表达,调用方无法区分 | 无法复位 / 无法重试 |
4.3 冻结前缀(历史快照,正文不回改)
| 冻结对象 | 处置 |
|---|---|
E-<nn> |
冻结于 E-63;引用照旧,禁止新增;门禁拒绝游标之外的新 E 号 |
docs/问题记录/项目审查与优化建议报告.md 自造的 N-xx/D-x/S-x/R-x/F-x/U1~U5 |
报告是历史基线,不回改;引用一律紧邻文档名;未闭环项已并轨进 N-19~N-29,出处列保留报告编号 |
docs/问题记录/CH395F_Trap_Records.md 2026-10-11 审计的 A1~A6/B1~B10 |
该表是审计快照(条目已修复或推翻),冻结;新发现进 DEF;引用紧邻文档名 |
P0-x~P3-x |
在册项迁 DEF;已闭环项留在历史文档,走别名表 |
Task #32 等会话临时号 |
禁止入册;现存引用(Src/main.c、Drivers/BSP/UI/ui_net_sink.c 的 I-1/I-2)改写为可解析形式或就地展开成事实描述 |
4.4 划界:这些不是编号,不受本规范管
| 对象 | 例子 | 归属 |
|---|---|---|
| C 标识符 | PS_OC1_EN、TEST_SUITE_STORAGE、ENABLE_PHASE14_TESTS、SYS_EVT_NET_READY、TASK_WD_ADC |
docs/代码规范/嵌入式C语言代码规范_V1.0.md |
| 元器件位号 | U1、C12、R3、L5、D7(docs/硬件平台/、docs/芯片手册/) |
门禁与改写脚本一律排除,这是最大误伤风险源 |
| 章节号 | §3.2 |
docs/文档规范.md §3.5 |
| 档位词 | P0/P1/P2/P3(严重度、用例优先级) |
允许继续使用,但永不带 -<数字> 后缀——P1-8 这类形态一律非法 |
| 图元 id | README.md 架构图 Mermaid 节点 A1/B1/C1/D2 |
改描述性 id(net/sto/ui),避免与条目字面撞名 |
| 运行时计数 | 网络代次号 net_get_generation() |
代码概念;与台架 GEN 是两回事,文档里须写全"网络代次号" |
5. 分配、引用、销项规则(强制)
5.1 新增编号
- 先问"能不能不加号":能用 § 小节引用、表格列、语义标题表达清楚的,就不要分配编号—— 编号是"确需跨文档长期引用"时才付的成本(P-1 / P-3 / P-7)。确需新增才往下走。
- 查 §4 总表确定类别与属主登记处;表里没有的类别 → 先改本规范,不得自造前缀。
- 到属主登记处取游标号(
scripts/id_registry.json记每类的游标与冻结状态),登记处新增一行。 - 严重度 / 状态 / 波次 / 出处写进表格列,不进编号。
5.2 引用写法
| 场景 | 写法 |
|---|---|
| 全局编号,跨文档首次出现 | `docs/任务规划/登记簿.md` N-21(紧邻,同 §N.M 规则) |
| 全局编号,同段后续 | `N-21` |
| 文档内编号 | 必须 `docs/网络/网络自愈架构设计.md` DR-003 |
| 尚未创建的条目文件 | 加 [计划] 前缀(docs/文档规范.md §3.3) |
| 引用报错样例/历史字面 | 该行加 [示例] 标记 |
5.3 代码注释引用
- 允许引用(长期有效):
FR-*、NFR-*、DEF-*、E-*(冻结存量)、N-*、TRAP-*、DR-*、TC-*、L<n>-<nn>。 - 禁止引用(易变):
WI-*、W<n>、MS-*、OQ-*、ST-*——代码是长期资产,波次与任务卡会变。 - 首次出现带属主文档名(现状 90% 裸引,靠"全库唯一"这一未成文假设)。
5.4 提交信息
标题带主编号:fix(net): N-32 监听重建阻塞导致心跳缺口。一次提交只挂一个主编号,其余进正文。
5.5 销项与归档
- 销项 = 删登记行 + 清全库引用(沿用
docs/任务规划/README.md§3 与AGENTS.md既有规则)+ 游标不回退。 - 号段用尽 → 扩位(
N-99→N-100),不换字母。 - 历史文档(审计报告、评审报告、已闭环陷阱)不回改,走别名表。
5.6 编号密集文档的对照节(强制)
一篇文档若引用 ≥3 个编号族(如 I* + E* + F-* + M* + U* + TRAP-*),必须在正文之前
加一节「导读:本文用到的编号与术语」——每个记号一行,给出「是什么 + 在哪查」,让读者不必跳出本文拼语义。
- 首次实践:
docs/网络/网络自愈架构设计.md的## 导读:本文用到的编号与术语。 - 对已封闭 / 已归档的编号族尤其必要:属主登记表可能已删行(
N-30N-33销项、E0E15随审计归档), 此时该文档即其唯一可查处。 - 与 P-7 配套:正文引用带语义括注(局部可读)+ 对照节给编号族总览(全局可查),两者合起来才算看得懂。
5.7 语义标识的登记、冻结与别名
- 登记:在属主登记处新增一行,
#列填短语本身;落笔前先grep确认同表内无同名 / 同义条目(同义异写 = 撞名,见 §3.3 形态规则)。 - 冻结:短语即标识,改措辞等于换 ID。确需改写时在原行加「别名」列,新旧措辞并存, 引用侧同步替换完成后再删旧名——禁止原地改写且不留下别名。
- 历史编号迁移:编号转语义标识时,原号进别名表(例:
N-18→8 路电气量分属两片转换器); 历史文档中的裸号不回改(§5.5 同款处置)。 - 销项:删行 + 清全库引用(沿用
docs/任务规划/README.md§3 与AGENTS.md既有规则); 短语不复用——重名即视为同一条目,与"号不回收"同理(撞名风险高于撞号,故由门禁兜底)。 - 代码注释:语义短语可进代码注释(中文注释允许),但必须带属主文档名(同 §5.3);
现状
App/algo/下N-18等 6+ 处裸编号引用违反 P-7,迁移时一并补语义。 - 门禁(
scripts/check_ids.py,§8,2026-10-20 已落地 warn-only):① 同一登记处内短语去重; ② 引用了登记处不存在的短语 = 悬空,报错;③ 打印「语义标识可判定比例」,只许涨不许跌。 ⚠ 当前落的是"编号"侧的 ②③(编号族的悬空与可判定比例已机械化);语义短语侧的 同表去重与短语悬空仍由人工 +grep执行——短语是自由文本,机械去重要先解决同义异写判定 (日志静默vs49s 日志静默),那是另一个问题,别把它记成"已由门禁兜住"。
6. 模块码表(TC / TM / DP / TRAP 共用)
现状是板端 6 个码 + 主机侧 10 个码两套并存,且 docs/测试说明/ADC输入层单元测试说明.md 明文豁免主机侧"与板端缩写表互不影响"。本规范合并为一张表,现有码全部沿用(零改写),只规定新模块必须先登记:
| 码 | 模块(源文件/目录) | 码 | 模块 |
|---|---|---|---|
NET |
Drivers/BSP/CH395F + Drivers/BSP/NET |
ADCIN |
App/algo/adc_input |
GD5F |
Drivers/BSP/GD5F2GQ5UE |
ADCHEALTH |
App/algo/adc_health |
STORAGE |
存储栈(FTL + FatFs + App/fs) |
PHASOR |
App/algo/phasor + sample_ring |
RTC |
Drivers/BSP/SD2506 |
PROTSET |
App/algo/prot_set |
ADC |
采集节拍与通道映射(Src/adc.c、TIM3) |
PROTELEM |
App/algo/prot_elm |
RS485 |
Drivers/BSP/RS485 |
VOLLOCK |
App/fs/vol_lock |
UI |
Drivers/BSP/UI |
TIMESYNC |
App/sync/time_sync |
LOG |
App/log |
SYSCLK |
App/util/sys_clock |
CONFIG |
App/cfg + Drivers/BSP/NETCFG |
WATCHDOG |
App/util/task_watchdog |
SHA256 |
App/util/sha256 |
FTPAUTH |
Drivers/BSP/NET/lftpd 鉴权 |
IEC104 |
App/protocol/iec104 |
TOOL |
PC 端工具(串口助手等) |
废止码:
PHY(→NET)、NAND(→GD5F)。历史文档不回改,新文档按本表。
⚠ 2026-10-20 批 2:上表 16 个有歧义的码已单词化(
AI→ADCIN、AH→ADCHEALTH、PS→PROTSET、PE→PROTELEM、PH→PHASOR、TS→TIMESYNC、VL→VOLLOCK、NP→NANDPORT、CFG→CONFIG、CLK→SYSCLK、WD→WATCHDOG、STO→STORAGE、SH→SHA256、FA→FTPAUTH、FR→FREQ、104→IEC104),全库 1,146 处随scripts/rename_ids.py改写,旧号入scripts/id_aliases.json。NET/GD5F/RTC/SOE/UI/ADC/LOG/RS485/TOOL不动(已是单词、芯片名或业界通用词)。连带修门禁:模块码变长到 9 位(ADCHEALTH),候选正则与族正则的{0,4}上界必须放宽到{0,9},否则改名后的号会整批从门禁眼里消失(实测漏掉 950 处——改名类批次必须连带复核识别面,不能只改数据不改判据)。
7. 迁移映射(legacy → 新号)
7.1 映射规则
| 旧族 | 新族 | 规则 |
|---|---|---|
登记簿 N-2…N-33(N-30~N-33 已销项,现存至 N-29) |
N-02…N-33 |
仅补零,数字不变;号不回收,游标仍 N-34 |
登记簿 S-3/S-4/S-5、T-7 |
N-34… |
续号并入,别名表保留旧号 |
主线 B0~B10、结构债 C1~C6、验证窗口 D2~D7、W1-0 |
WI-001… |
按波次顺序连续重编,映射表逐条列出并落别名表 |
复审 S1~S14、A-1~A-7、报告 R-x/F-x/U1~U5 未闭环项 |
WI-* |
同上;已闭环项留历史文档 |
P0-x~P3-x 在册项 |
DEF-* |
严重度转列 |
设计说明 D1~D10 |
DR-001~DR-010 |
数字对齐 |
B0-a/b/c、待确认-N |
OQ-001… |
— |
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 不动(两套不同尺度,不合并) |
gen 181/gen-288/gen68 |
GEN-181/GEN-288/GEN-068 |
数字不变 |
round 1~9 |
RUN-<日期>-<n> |
无日期的历史轮次留别名表 |
M1~M3 |
MS-01~MS-03 |
— |
对账 ①~④ |
RC-01~RC-04 |
代码注释同步 |
审计模式 P1~P9 |
PAT-01~PAT-09 |
正文冻结,新文档用新号 |
保护 R1~R8、看门狗 R1~R7 |
各文档 RSK-01… |
文档内编号 + 引用带文档名 |
保护阶段 P0~P5、方案 P0~P3 |
各文档 ST-0… |
与档位词 P0 解耦 |
TC-STORAGE-01~06 |
TC-STORAGE-001~006 |
补零 |
TC-ADCIN-01A/02A/02B/02C、TC-VOLLOCK-008b |
TC-ADCIN-001a… / TC-VOLLOCK-008b |
后缀统一小写字母,基号补零 |
TM-PHY-01~11 |
TM-NET-01~11 |
模块码 |
DP-01~04 |
DP-NET-01~04 |
加模块码 |
7.2 孤儿编号处置(阶段 1 一并清)
| 孤儿 | 处置 |
|---|---|
I-1/I-2(ui_net_sink.c) |
就地展开成事实描述(原属主《网络Socket监听生命周期设计说明》已并入 docs/网络/网络自愈架构设计.md §9.3,不再补编号定义行) |
Task #32 会话号及其小节引用 |
会话号,改写为可解析引用(结论已沉淀进 docs/子系统设计/看门狗设计说明.md §11) |
P1-01~P1-09(ch395f_test_task.c) |
改指 TC-NET-101…,或补文档条目 |
TC-GD5F-1100/1101/1102、TC-STORAGE-06 |
补进 docs/测试说明/GD5F2GQ5UE_Test_Guide.md |
TC-AH-*、TC-PE-*、iec104 TC-014/015/024 |
补单测说明文档(缺文档 = 追溯断链) |
Trap 19 |
悬空引用,删除或改指实际条目 |
7.3 改写操作规程(每批必走)
# 1) 预览:映射表驱动的 dry-run,人工通读 diff(重点看 docs/硬件平台/ 是否被误伤)
& '.venv\Scripts\python.exe' [计划] scripts/rename_ids.py --map [计划] scripts/id_aliases.json --dry-run
# 2) 落盘后三重复核
git grep -n '<旧字面量>' # 零残留
& '.venv\Scripts\python.exe' scripts/check_doc_links.py --all
& '.venv\Scripts\python.exe' .dsh\skills\keil-build\scripts\keil_build.py # 0 错误 0 警告
硬约束:docs/硬件平台/、docs/芯片手册/ 全程排除(元器件位号 U1/C12/R3/L5/D7 与编号字面同形);带 BOM 的文件(Drivers/BSP/UI/*、App/task/ui_task.c、App/cfg/cfg_file.c、Lib/lv_conf.h)改写后必须核对 BOM 未丢;禁止用 Get-Content/Set-Content 重写含中文文件。
8. 门禁:check_ids.py 与 id-check 钩子
配置两份:scripts/id_registry.json(前缀 → 属主文档 / 形态正则 / 是否冻结 / 游标)、scripts/id_aliases.json(旧号 → 新号,照搬 scripts/section_aliases.json 的成功范式)。
| # | 校验 | 级别 |
|---|---|---|
| 1 | 出现未登记前缀(自造编号) | 错误 |
| 2 | 形态不合规:裸形 S3、空格形 Trap 07、中文形 陷阱 1、补零错、P1-8 这类档位词带后缀 |
错误 |
| 3 | 引用查无定义且不在别名表(悬空引用) | 错误 |
| 4 | 同一字面量被两个属主重复定义(N-16 类事故) |
错误 |
| 5 | 冻结前缀出现游标之外的新号 | 错误 |
| 6 | 文档内编号引用未紧邻文档名 | 错误 |
| 7 | 定义了但全库无引用(孤儿条目) | 告警 |
| 8 | 打印**「编号引用可判定比例」** | 每次运行,只许涨不许跌 |
- 排除:
Lib/、Middlewares/、HAL/CMSIS、docs/芯片手册/、docs/硬件平台/(位号)、构建产物。 - 上线节奏:先 warn-only → 2026-10-21 关闸为【增量拦截】(
--strict+ 债务台账,见 §8.4)。与doc-links的差别在于:存量太多(710 处),等清零会逼出--no-verify,所以先关闸再还债。 - 顺带收编
scripts/check_test_traceability.py:正则补齐大写后缀与无模块码形态,覆盖 7 篇「单元测试说明.md」,一并挂进id-check。 2026-10-21 口径改写(B 层之后):差异分三档——DOC-ONLY文档声明而代码没有(真断链)、CODE-ONLY代码有而母号不在登记处且号旁无意图(真未登记)、IN-CODE靠「代码旁写着意图」放过(弱保证,单列示数、不算过关);小写子项后缀按母号算。
8.1 落地记录(2026-10-20)
已落地并挂上 id-check 钩子(warn-only)。三项机械判据先定死,否则八项校验全是空话:
| 判据 | 口径 |
|---|---|
| 「定义」存在 | 字面量出现在该族的属主登记处文档里(registry 的 owner_docs / owner_docs_glob)——不依赖表格行首等易漂移形态 |
| 「重复定义」 | 字面量出现在定义位(表格首格 / 标题行 / 列表项行首);正文里"提到过"不算定义,否则任何交叉引用都会被误判 |
| 「可判定」 | 字面量落进已登记前缀族且该族属主登记处已存在;未登记前缀、属主还是 [计划] 的都算不可判定 |
首轮基线(本仓库实测,--update-baseline 写进 id_registry.json,只许涨不许跌):
| 项 | 数值 |
|---|---|
| 扫描文件 | 536 个(git ls-files 减去 §8 排除清单) |
| 编号字面量出现 | 8271 处 |
| 可判定比例基线 | 82.6%(6840 / 8271 = 82.70%,批 1 改名后重打,存进 id_registry.json 时下取整到 0.1pp——用 round() 会让 82.34 进位成 82.3 再反过来把自己判死,实测踩过;比较容差 0.1pp) |
| 校验 1 未登记前缀 | 0 处 |
| 校验 2 形态不合规 | 396 处(批 1 已从 417 降到 396:裸形 S/T 类 71 → 50。剩余大头:真无模块码 TC-nnn 181 处 / 5 文件、数字模块码 TC-104-nnn 23 处(§6 表里模块码是 I104,非数字)、DP-01~DP-04 22 处、Task #nn 33 处、Trap 空格形+陷阱 中文形 43 处、gen/round 36 处、大写后缀 31 处) |
| 校验 3 悬空引用 | 错误 626 / 告警 223(scoped 别名收编旧号后 −16)(错误集中在 TC-PS-*/TC-PE-*/TC-AH-*/TC-FR-*/TC-SOE-*——主机侧单测有码无文档,正是 §7.2 列的"缺文档 = 追溯断链") |
| 校验 4 重复定义 | 0 处(§4.3 已声明的同号不同义族对 443 个字面量走 collides_with 白名单,不计事故) |
| 校验 5 冻结越游标 | 0 处 |
| 校验 6 未紧邻文档名 | 269 处(报告自有编号 D-x/R-x/F-x/P0-x 被裸引,属 §9 阶段 1-③ 待办) |
| 校验 7 孤儿条目 | 88 处(告警) |
| 附带 TC 双向追溯 | 代码侧 556 / 文档侧 290 / 交集 260(差异 326,收编后含主机侧单测一侧,比原板级口径的 33 大一个量级——原口径漏的正是 7 篇单测说明) |
有牙实测([示例] 下列字面量是注入用的假编号,不是真实引用):临时注入 Z-99 / 裸形 S3 / TC-NET-9999(悬空)/ E-70(越 E-63 游标)/ 裸引 D-7 / 在第二篇属主文档重复定义 DP-01 → 六项分别被校验 1/2/3/5/6/4 点名,--strict 退出码 1;临时档删除后 git status 干净。
口径修正记录(2026-10-21,B 层)——下列改动改变了比例的分母/分子含义,读历史数字必须知道:
| 改动 | 动机 | 对比例的影响 |
|---|---|---|
主机侧单测建 9 族 TC-HOST-<模块码>,属主登记处 = test/host/<目录>/*(代码即登记处) |
实测这些号在代码目录外零消费者(唯一"外部引用"是 id_aliases.json 自己),逐号补文档只会造出没人读的复述层 |
悬空错误 −508 中的 430(口径修正,不是仓库变好) |
subitem_ok:小写子项后缀(TC-TIMESYNC-003b)母号在册即算已定义 |
§4.1 明允许小写后缀,是合法形态;双向追溯仍按完整字面量报差异,可见性不丢 | 悬空 −74(同上,属口径) |
snapshot_only:§4.3 冻结历史快照族(N-RPT/D-RPT/S-RPT/R-RPT/F-RPT/P-AUDIT/A-AUDIT/B-AUDIT)不参与"定义位优先" |
曾试过让定义位优先无差别生效:N-21(登记簿条目已销项)被审计报告里同号的另一码事"接管",门禁转而去报 ⑥"请写报告文档名"——照做就制造 §1.2 的 N-31 撞号;实测该做法使校验 6 从 266 暴涨到 1437、比例假崩到 68.7% |
校验 6 回到 269(与 B 层前持平) |
补属主:docs/任务规划/README.md 加入 N/S-LDG/T-LDG 族的 owner_docs |
这是我的配置漏项:活登记处在 README(N-21 出现 2 次),我原先只登记了 登记簿.md(N-21 = 0)→ 真条目被误判悬空 74 处 |
悬空 −74(修 bug,不是口径) |
excluded_paths 加 scripts/id_aliases.json、scripts/id_registry.json |
别名表/注册表自身不得制造引用面——上批别名条目一度成为这些号的唯一"外部引用" | 极小 |
追溯脚本同口径对齐(check_test_traceability.py):文档声明了代码没有 = DOC-ONLY 真断链(38);代码有、母号不在登记处且号旁没写人话意图 = CODE-ONLY 真未登记(7);代码有但旁边写着意图 → 单列 IN-CODE(238),弱于文档的保证,禁止当成已登记 |
B 层认代码为属主后,老口径「每个号都必须出现在文档」与门禁自相矛盾——照它升 --strict 会拦死 173+ 处本不该写文档的号,逼出 --no-verify,门禁公信力就是这么没的 |
差异从 284 降到 45(38+7),另 238 处转入「看得见但不过关」的 IN-CODE 账 |
⚠ 同批改名要复核所有识别面:TC_RE 也停在 {0,4},模块码单词化后代码侧集合从 556 悄悄缩到 217(339 个号隐形),已放宽到 {0,8} |
这是「改名必须连带复核判据面」教训的第二次发生,发生在另一支脚本上 | 修回后代码侧 578 |
已销项历史任务号 T-2/T-3/T-4/T-6 入别名表(status: void) |
§5.5「销项 = 删行 + 清引用」只做了一半的欠账;本条只让门禁停止把它当自造号,并如实指路 | 悬空错误 −35 |
修正后实测(2026-10-21):错误级 711(B 层前 1318)= ②398 + ③44 + ⑥269;告警级 ③223 + ⑦100;可判定比例 82.71%(6883/8322),基线仍 82.6%。 ⚠ 拿 711 与 1318 直接比是错的——其中 504 处是口径修正,只有 74 处是我修的注册表 bug;真正"变好"的部分是 0。剩下的 711 处没有一条能靠调判据消掉,只能补文档、改写引用或按 §4.3 登记冻结。
显式盲区(不是"检查通过",是记在案上的判定边界):裸形同字母多义(§1.2 的 P1 五义 / L1 四义 / U1 四义 / D7 三义)与元器件位号同形(§4.4)→ 裸形族只在属主登记处文档内判越游标,文档外降为告警;圈号编号与正常列举无法机械区分,不入判定。这两块的收口属 §9 阶段 1-②/1-③ 的迁移批次,收口后再扩判定范围。
8.2 落地时发现的规范 ↔ 仓库偏差(registry 按实测收录,规范行待订正)
| 规范原文 | 实测 | 处置 |
|---|---|---|
§4.1 E\d+「已封闭 E0~E15」 |
docs/网络/网络自愈架构设计.md §5.2 实验表已到 E19 |
游标按实测 E19 收录;封闭线待修订 |
§4.1 FR-[A-Z0-9]+-\d{2} |
现存 FR-STO-1 等全是未补零的 1 位序号 |
正则放宽到 \d{1,2},补零归 §9 阶段 1 |
§4.1 TC-[A-Z]{1,4}-\d{3,4} |
模块码 GD5F/I104 含数字,按原文正则会漏掉 GD5F 全族(实测 285 处) |
放宽为 [A-Z][A-Z0-9]{0,4};序号暂收 2 位(TC-STORAGE-06 属 §7.2 孤儿) |
§4.1/§4.2 总表无 F-<MOD>-<nn> |
F-NET-2~17/F-DRV-*/F-MS-* 定义在 docs/网络/网络自愈架构设计.md 且被大量代码注释引用 |
先按实测收编成族(§5.1 第 1 步:表里没有的类别先改本规范) |
§4.1 N-\d{2} |
报告用 N-03a/N-03c 子项后缀;§5.5 扩位示例 N-100 |
放宽到 \d{1,3}[a-z]? |
8.3 迁移批次记录(改名走 scripts/rename_ids.py)
| 批 | 日期 | 族 | 旧 → 新 | 处数 / 文件 | 别名 |
|---|---|---|---|---|---|
| 批 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 | 代码规范条款 | S1S19 → CODE-RULE-0119 |
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 文件 | 全局别名(字面量已完全限定,无歧义) |
| 批 1 | 2026-10-20 | UI 像素回归状态 | S0S7 → MENU-STATE-0007 |
61 处 / 3 文件 | 8 条(scoped:simulator/tests/check_menu_rows.py、docs/UI设计/UI_自动化测试流程.md、simulator/README.md) |
⚠ 别名必须带 scope:同一裸形字面量可同时是多族的旧号(实测 S3 三义)。全局别名会把另一族的真悬空洗成「已解析」——等于用工具复制 §1.2 的 N-31/N-32 撞号事故。
批 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),
靠人清完要数周到数月;这期间新欠的债一条都不会被拦——而新增恰恰是编号烂掉的主因(N-31/N-32 撞号
就是新增时撞上的)。更糟的是「等清零」会让所有人习惯看到「门禁报红但照样提交」,真到关闸那天已经没人信它。
机制:--strict 不再「有任何错误就失败」,而是只拦台账之外的新错误级问题。
| 件 | 说明 |
|---|---|
| 台账 | scripts/id_known_backlog.json:340 条指纹,覆盖 710 处错误级问题(② 167 类 / ⑥ 135 类 / ③ 38 类) |
| 指纹 | (文件, 校验号, 字面量) → 出现次数。故意不含行号:行号每改必漂,拿它当指纹会让台账天天「假新增」,三天后没人敢看 strict 输出,台账等于失效——台账失效比没有台账更糟 |
| 为什么带计数 | 同一文件里同一个号多出现一次也算新账:复制粘贴式扩散是编号烂掉的常见路径,只按「有没有出现过」判会放过它 |
| 只减不增 | --prune-backlog 收掉已还清条目;台账内条目变多会被 --strict 当场拦;确需新增一条必须写 reason 字段(默认禁止顺手加行,否则一周后台账变成第二个 backlog) |
| 初始化 | --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 同一条道理:登记号的表不是引用号的文档。第 4 次同样自循环:改名映射表 scripts/rename_maps/batch3-trap.json 里必然写着 Trap 21 / 陷阱 1 这些旧形态,关闸后第一次提交就被它自己拦下 6 类「新账」→ 整个 scripts/rename_maps/ 目录一并入 excluded_paths(它是审计轨迹,不是引用语料) |
关闸验收(三例,2026-10-21 实测):
| 情况 | 期望 | 实测 |
|---|---|---|
A 全新未登记前缀(Z-99)[示例] |
拦 | exit 1,+1 [校验1] docs/tmp_teeth_a.md Z-99 ✅ |
| B 同一文件里已登记的号多出现一次(计数 1→2) | 拦 | exit 1,+1 [校验6] ui-verify/SKILL.md 内的 R-9 ✅ |
| C 干净态(710 处存量全在台账内) | 放行 | exit 0,增量拦截通过 ✅ |
临时注入文件与追加行当场还原(git diff 干净)。C 例最关键:放不住存量就会逼出 --no-verify,
那是把门禁从「闸」降级成「报表」——本仓已有 mem-budget / mem-numbers 走 --no-verify 的先例,别再开第二个口子。
9. 落地阶段与验收
| 阶段 | 内容 | 验收判据 | 风险 |
|---|---|---|---|
| 0 规范 | 本文件;docs/任务规划/README.md §0 改为指向本规范的摘要;docs/README.md、AGENTS.md、docs/文档规范.md §6 登记;两份 id_*.json 初版 |
check_doc_links --all 通过、@build 0/0 |
零(纯新增 + 指针) |
| 0.5 语义标识 | §3.3 / §5.7 规范落地:登记簿、排期、波次的存量条目转语义短语(原号进别名表,N-x/S-x/T-x/B/C/D);代码注释裸编号(如 N-18)补语义;DEF/WI/OQ/RSK/DR/GAP/SC 按语义形态启用 |
每批:dry-run 通读 → 落盘 → git grep 零残留 → check_doc_links --all → @build 0/0 |
中(撞名与措辞漂移是主要风险) |
| 1-① 小族 | RC/PAT/GEN/RUN/MS/GAP/SC/OQ/RSK/DR/TRAP/ST/UL/LAT/CS + Mermaid 节点 id + 孤儿处置 |
每批:dry-run 通读 → 落盘 → git grep 零残留 → check_doc_links --all → @build 0/0 → ci_local.py |
中 |
| 1-② 大族 | N 补零 + S/T 并入;WI ← B/C/D/W1-0/S1x/A-x/R-x/F-x/U-x;测试分层 L0~L3 → T0~T3(最大机械批次,L0.5 一词全库百余处) |
同上,逐族一个 commit | 高 |
| 1-③ 缺陷族 | DEF ← P0-x~P3-x 在册项;报告历史编号补齐紧邻文档名;档位词规则落地;别名表与游标定稿 |
同上 | 中 |
| 2 门禁 | ✅ 已落地(2026-10-20,warn-only):scripts/check_ids.py + id-check 钩子 + scripts/id_registry.json / scripts/id_aliases.json;check_test_traceability.py 已收编(正则补齐 + 纳入 7 篇「单元测试说明.md」与 test/host/ 一侧) |
全库告警清零后 entry 加 --strict 转拦提交;可判定比例基线 82.6% 已入档(批 1 改名后由 82.3% 抬升)(§8.1,写在 id_registry.json 里,跌破即失败) |
中(首轮确实暴露出 626 处真悬空 + 416 处形态违规 + 269 处未紧邻文档名,见 §8.1) |
每阶段结束停下等指令再提交(AGENTS.md 边界:commit/push 须明确指示)。
10. 常见错误速查
| 现象 | 原因 | 修复 |
|---|---|---|
id-check 报"未登记前缀" |
自造了一套编号 | 查 §4 总表归到既有类别;确属新类别先改本规范 |
| 同一编号在两篇文档各指一物 | 用了文档内编号却裸引 | 改全局编号,或引用补文档名(紧邻) |
| 引用的编号查不到定义 | 孤儿/悬空 | 补定义行,或删引用 |
| 降级后编号与事实不符 | 语义进了编号 | 违反 P-2;严重度改列,编号不动 |
硬件文档里 U1/C12 被改 |
改写脚本没排除位号目录 | 回滚该批,按 §7.3 排除清单重跑 |
| 改完中文变乱码 | 用了整文件重写 | 见 AGENTS.md 铁律:只用精确子串替换,BOM 按原样补回 |
变更记录
| 日期 | 变更 | 说明 |
|---|---|---|
| 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 口径修正记录表 |
| 2026-10-20 | 编号改名开禁(用户授权)+ 批 1 落地 | 新增 scripts/rename_ids.py(§7.3 规划脚本:映射表驱动、显式 scope、干跑/落盘两态、自动写 id_aliases.json 的 scoped 条目、跳过 [示例]/[计划] 行与变更记录表、按原字节读写保 BOM 与行尾)。批 1:代码规范条款 S1~S19 → CODE-RULE-nn(78 处/2 文件)、UI 像素回归状态 S0~S7 → MENU-STATE-nn(61 处/3 文件);check_ids.py 支持 scoped 别名 并登记两族(66 族);可判定比例 82.3% → 82.7%、裸形判错 71 → 50、错误级 1312 → 1291。§4.1 补两行、新增 §8.3 迁移批次记录 |
| 2026-10-20 | §8 门禁落地(warn-only) | 新增 scripts/check_ids.py(八项校验 + 可判定比例基线)、scripts/id_registry.json(逐项来自 §4 总表 + 实测游标)、scripts/id_aliases.json;挂上 id-check 钩子(36→37);顺带收编 check_test_traceability.py(正则补齐大写后缀/无模块码形态,比对范围扩到 7 篇「单元测试说明.md」+ test/host/ 一侧,另加 --board-only 回退原口径)。新增 §8.1 落地记录(基线 82.3%、backlog 分布、有牙实测、显式盲区)与 §8.2 规范↔仓库偏差表(E19、FR 未补零、TC 模块码含数字、F-<MOD>-<nn> 总表缺行、N 子项后缀/扩位);§4.1 相应行按实测订正并补 F-<MOD> / P-<n> 两行 |
| 2026-10-15 | 新增 P-8 与语义标识规范(§3.3 / §5.7) | §2 加 P-8「语义优先」(规划 / 待办类条目优先用语义标识,不发字母+数字号)→ 七条原则变八条;§3 主轴由"两层编号"扩为编号 / 语义标识 / 章节引用三种;新增 §3.3「语义标识(新条目默认形态)」(形态规则、适用分界、引用写法)与 §5.7「语义标识的登记、冻结与别名」;§4.2 加修订说明(规划类前缀改语义标识,TC/TRAP/FR/NFR/RC 等保留编号);§9 加「0.5 语义标识」阶段。起因:用户裁定去除字母数字编号(难理解),先定规范本体 |