From 858434492cd1ea3945520837e7f4fccf3602ff56 Mon Sep 17 00:00:00 2001 From: Wanderingss <1624155937@qq.com> Date: Wed, 21 Oct 2026 11:35:30 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E9=97=A8=E7=A6=81):=20id-check=20?= =?UTF-8?q?=E5=85=B3=E9=97=B8=E2=80=94=E2=80=94=E6=8C=89=E5=80=BA=E5=8A=A1?= =?UTF-8?q?=E5=8F=B0=E8=B4=A6=E5=A2=9E=E9=87=8F=E6=8B=A6=E6=88=AA=EF=BC=8C?= =?UTF-8?q?warn-only=20=E6=97=B6=E4=BB=A3=E7=BB=93=E6=9D=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 机制(--strict 不再「有错就失败」,而是只拦台账外的新账) - scripts/id_known_backlog.json:340 条指纹覆盖 710 处存量(②167 类 / ⑥135 / ③38) - 指纹 = (文件, 校验号, 字面量) → 计数,故意不含行号:行号每改必漂, 用它当指纹会让台账天天假新增,三天后没人敢看 strict,台账失效比没台账更糟 - 带计数而非集合:同一文件里同一个号多出现一次也算新账(复制粘贴式扩散 正是编号烂掉的主路径,只按「出现过没有」判会放过它) - 新增 --write-backlog 与 --prune-backlog(只减不增;台账内条目变多当场点名); --strict 缺台账返回 2,绝不退化成一次性拦死存量;--only 与 --strict 互斥 - 钩子 entry 加 --strict;--only 与 --strict 互斥 - 顺带修 _scan_malformed 的反向 bug:原条件 (skip and name != "空格形 Trap") 语义正好写反,带 [示例] 的行反而专被 Trap 规则咬;改为示例行全部不判 - 第一次提交就被自己的台账咬住(id_known_backlog.json 里当然写着 P1-3 等号, 被当成新引用)→ 台账加入 excluded_paths:登记号的表不是引用号的文档, 与 id_aliases.json / id_registry.json 同一条道理 为什么不照「清零再升 strict」的原节奏(§8.4 详述) - 存量 710 处清完要数周,这期间新债一条都不拦,而新增才是烂掉主因 - 「等清零」让人习惯「报红但照样提交」,真关闸那天没人再信门禁; 本仓已有 mem-budget / mem-numbers 走 --no-verify 的先例,不再开第二个口子 关闸验收三例(临时件当场还原、git diff 干净) - A 全新前缀 Z-99 → exit 1 点名 ✅ 咬 - B 同号计数 1→2 → exit 1 点名 ✅ 咬 - C 干净态 710 处 → exit 0 放行 ✅ 放(放不住存量就会逼出 --no-verify) 验证:--strict 干净态 exit 0;可判定比例 82.74%(基线 82.6%); doc-links 失效/待确认 0;未改 C/H 不需 @build。 文档:编号规范 §8 上线节奏改写 + 新增 §8.4 机制表;pre-commit使用说明 §2.25; AGENTS.md 门禁行由 warn-only 改为已关闸增量拦截。 --- .pre-commit-config.yaml | 2 +- AGENTS.md | 2 +- docs/代码规范/pre-commit使用说明.md | 2 +- docs/编号规范.md | 33 +- scripts/check_ids.py | 104 +- scripts/id_known_backlog.json | 2049 +++++++++++++++++++++++++++ scripts/id_registry.json | 3 +- 7 files changed, 2184 insertions(+), 11 deletions(-) create mode 100644 scripts/id_known_backlog.json diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a9bf27a0..eddf27fa 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -544,7 +544,7 @@ repos: # (悬空/孤儿/重复定义是跨文件判定,pass_filenames: false)。 - id: id-check name: 编号门禁(docs/编号规范.md §8 八项校验) - entry: python scripts/check_ids.py + entry: python scripts/check_ids.py --strict language: system files: \.(md|c|h|py|ya?ml|json|txt)$|^\.pre-commit-config\.yaml$ pass_filenames: false diff --git a/AGENTS.md b/AGENTS.md index c8c4cebe..e5e937c5 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -90,7 +90,7 @@ ## 提交门禁(pre-commit) -- 任一失败即拦截,共 **37 个钩子**(逐个详解 → `docs/代码规范/pre-commit使用说明.md`):通用 5 + `gitlint` + `cppcheck` / `test-cppcheck` + `no-mojibake` + `coding-standard` + 文档三件套 `doc-links` / `task-table` / `mem-numbers` + `id-check`(**编号门禁**,`docs/编号规范.md` §8 八项校验;**当前 warn-only**,可判定比例跌破 `id_registry.json` 基线才失败)+ `lv-conf-sync`(两份 `lv_conf.h` 特性子集一致)+ `cubemx-survival` + 主机侧单测 16 个(`-unit-test` 后缀)+ `test-suite-switch` + `registration-check`(双端注册反向校验 + UI 页面描述符表接线,N-23/U4)+ `mem-budget`(RAM 92% 预算门禁,N-27)+ `font-charset`(UI 字符集差集检查,防缺字白框,U4)+ `ui-golden`(UI 像素回归,菜单 8 状态 + 内容页 11 页黄金参考,U4) +- 任一失败即拦截,共 **37 个钩子**(逐个详解 → `docs/代码规范/pre-commit使用说明.md`):通用 5 + `gitlint` + `cppcheck` / `test-cppcheck` + `no-mojibake` + `coding-standard` + 文档三件套 `doc-links` / `task-table` / `mem-numbers` + `id-check`(**编号门禁**,`docs/编号规范.md` §8 八项校验;**已关闸为【增量拦截】**:只拦 `scripts/id_known_backlog.json` 台账之外的新错误级问题,存量按指纹豁免、台账只减不增;另有一根恒生效的线——可判定比例跌破 `id_registry.json` 基线即失败)+ `lv-conf-sync`(两份 `lv_conf.h` 特性子集一致)+ `cubemx-survival` + 主机侧单测 16 个(`-unit-test` 后缀)+ `test-suite-switch` + `registration-check`(双端注册反向校验 + UI 页面描述符表接线,N-23/U4)+ `mem-budget`(RAM 92% 预算门禁,N-27)+ `font-charset`(UI 字符集差集检查,防缺字白框,U4)+ `ui-golden`(UI 像素回归,菜单 8 状态 + 内容页 11 页黄金参考,U4) - **范围 = 项目代码**:第三方(`Lib/`、`Middlewares/`、CMSIS、HAL、`lftpd`、`dhara`、`MDK-ARM`)排除;`cppcheck`/`coding-standard` 另排除 `test/`,规范检查再排除 CubeMX 生成的 `Src/`/`Inc/`。**`simulator/` 已纳入全部钩子**(2026-10-11)——生成物只靠 `.gitignore` 挡,**不在 `exclude` 里写目录名**(教训见 `docs/代码规范/pre-commit使用说明.md` §5.5) - ⚠ **pre-commit 4.x 已移除 `always: true`**(实测对 `local` 钩子只告警 `Unexpected key(s)` 并跳过)→ 想"总是跑"的钩子**必须让 `files:` 覆盖到所有会触发它的文件**,没有兜底开关 - **改写型钩子(`trailing-whitespace` + `end-of-file-fixer`)豁免 CubeMX/Keil 生成文件**(配置里 YAML 锚点 `&cubemx-generated`);⚠ **只读检查不受影响**:`cppcheck` / 乱码 / `cubemx-survival` / `task-table` / `mem-numbers` 仍覆盖 `Src/`、`Inc/` diff --git a/docs/代码规范/pre-commit使用说明.md b/docs/代码规范/pre-commit使用说明.md index 4747a2f3..86a64d58 100644 --- a/docs/代码规范/pre-commit使用说明.md +++ b/docs/代码规范/pre-commit使用说明.md @@ -451,7 +451,7 @@ cppcheck 是开源 C/C++ 静态分析工具,**不运行代码**,通过语法 | 项 | 说明 | |---|---| | **触发条件** | 任意 `.md` / `.c` / `.h` / `.py` / `.yaml` / `.json` / `.txt` 或本配置文件变动(pre-commit 4.x 无 `always: true`,`files:` 按扩展名覆盖全触发面);**`pass_filenames: false`**——悬空引用 / 孤儿条目 / 重复定义是**跨文件**判定,只喂变更文件必然判错,故每次恒扫全库(实测 536 个文件 1.1 s,够快) | -| **处理方式** | **当前 warn-only**(`docs/编号规范.md` §8 上线节奏:先清 backlog → 清零后 `entry` 加 `--strict` 拦提交,与 `doc-links` 章节校验同一条路径)。**唯一例外**:校验 8 的「可判定比例」跌破 `scripts/id_registry.json` 里的基线(82.3%)→ **任何模式都 FAIL**,这根线就是防回退的本体 | +| **处理方式** | **2026-10-21 已关闸为【增量拦截】**:`entry` 带 `--strict`,只拦**台账之外**的新错误级问题;存量 710 处按 `scripts/id_known_backlog.json` 的指纹豁免(指纹 = 文件 + 校验号 + 字面量 + 计数,**故意不含行号**——行号会漂,用它当指纹台账天天假新增)。台账只减不增:`--prune-backlog` 收已还清的,条目变多或出现新字面量都当场拦;`--strict` 缺台账直接返回 2,**不退化成一次性拦死存量**(那会逼出 `--no-verify`)。另有一根恒生效的线:可判定比例跌破 `id_registry.json` 基线(82.6%)→ 任何模式都 FAIL | | **八项校验**([示例] 本行引用的是各种非法形态示例,不是真实编号) | ①未登记前缀 ②形态不合规(裸形 `S3` / 空格形 `Trap 07` / 中文形 `陷阱 1` / 补零错 / 档位词带后缀 / 大写后缀 / 缺模块码)③悬空引用 ④重复定义 ⑤冻结前缀越游标 ⑥文档内编号未紧邻文档名 ⑦孤儿条目(告警)⑧可判定比例(只许涨不许跌) | | **配置两份** | `scripts/id_registry.json`:前缀族 → 属主登记处 / 形态正则 / 是否冻结 / 游标,**逐项来自 `docs/编号规范.md` §4 总表**,游标取「规范记载值」与「全库实测最大号」的较大者,偏差写进 `cursor_note`(实测偏差见规范 §8.2);`scripts/id_aliases.json`:旧号 → 新号 / 作废标记(照搬 `section_aliases.json` 的成功范式) | | **判定口径** | 「定义」= 字面量出现在该族**属主登记处文档**里(不依赖表格行首等易漂移形态)→ §5.5「销项 = 删行 + 清全库引用」只做一半,校验 ③ 立刻报(`N-31`/`N-32` 正是这条)。「重复定义」= 字面量出现在**定义位**(表格首格 / 标题行 / 列表项行首),正文提到不算,否则任何交叉引用都会误判成事故。多族同形时的定族顺序:所在文档即属主 > 紧邻属主线索 > **定义位优先**(`docs/编号规范.md` §4.3 冻结快照族 `N-RPT`/`D-RPT`/`S-RPT`/`R-RPT`/`F-RPT`/`P-AUDIT`/`A-AUDIT`/`B-AUDIT` **不参与**——否则已销项的登记簿 `N-21` 会被审计报告同号接管,门禁反过来教人补错文档名,实测把校验 6 从 266 撑到 1437、可判定比例假崩到 68.7%)> 判悬空的族 > 全局族;小写子项后缀(`-b`/`-c`)在母号在册时视为已定义(`subitem_ok`),差异仍由双向追溯如实报 | diff --git a/docs/编号规范.md b/docs/编号规范.md index d48f1698..1d5ea1fd 100644 --- a/docs/编号规范.md +++ b/docs/编号规范.md @@ -381,7 +381,7 @@ git grep -n '<旧字面量>' # 零残留 | 8 | 打印**「编号引用可判定比例」** | 每次运行,只许涨不许跌 | - 排除:`Lib/`、`Middlewares/`、HAL/CMSIS、`docs/芯片手册/`、`docs/硬件平台/`(位号)、构建产物。 -- 上线节奏:**先 warn-only 清 backlog → 清零后加 `--strict` 拦提交**(与 `doc-links` 章节校验完全同一条路径)。 +- 上线节奏:**先 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` 靠「代码旁写着意图」放过(弱保证,单列示数、不算过关);小写子项后缀按母号算。 @@ -457,6 +457,36 @@ git grep -n '<旧字面量>' # 零残留 --- +### 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` 同一条道理:**登记号的表不是引用号的文档**) | + +**关闸验收(三例,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. 落地阶段与验收 | 阶段 | 内容 | 验收判据 | 风险 | @@ -491,6 +521,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 | **关闸:`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 迁移批次记录 | diff --git a/scripts/check_ids.py b/scripts/check_ids.py index 1128a9e7..fb5de1f4 100644 --- a/scripts/check_ids.py +++ b/scripts/check_ids.py @@ -612,11 +612,56 @@ def parse_only(s): return {int(x) for x in re.split(r"[,\s]+", s) if x.strip().isdigit()} +BACKLOG_FILE = REPO_ROOT / "scripts" / "id_known_backlog.json" + + +def err_groups(ck): + """当前错误级问题按 `(文件, 校验号, 字面量)` 归并计数——**债务台账的指纹**。 + + 指纹故意**不含行号**:行号每编辑一次就漂移,拿它当指纹会让台账天天"新增", + 三天后 strict 输出全是假警报,没人敢再看——台账失效比没有台账更糟。 + 用**计数**而不是集合:同一文件里同一个号第 N+1 次出现必须能抓出来, + 复制粘贴式扩散正是编号烂掉的常见路径(§1.2 的跨文档同号不同义就这么来的)。 + """ + g = defaultdict(int) + for f in ck.findings: + if f.severity == "error": + g[(f.rel, f.code, f.literal)] += 1 + return g + + +def load_backlog(): + """台账 → {(file, code, literal): count};文件不存在返回 None。""" + if not BACKLOG_FILE.is_file(): + return None + doc = json.loads(BACKLOG_FILE.read_text(encoding="utf-8")) + return {(e["file"], int(e["code"]), e["literal"]): int(e["count"]) + for e in doc.get("entries", [])} + + +def backlog_doc(entries, errs, ratio): + return { + "schema": 1, + "note": ("编号债务台账(docs/编号规范.md §8.4):--strict 只对**台账之外**的新错误级问题拦提交。" + "台账只许减不许增——还清的用 --prune-backlog 收掉;确需新增一条必须写 reason 字段" + "说明这笔债为什么该存在,默认禁止顺手加行(否则一周后台账就变成第二个 backlog)。" + "指纹 = 文件 + 校验号 + 字面量,不含行号(行号会漂,用它台账天天假新增)。"), + "generated_by": "scripts/check_ids.py --write-backlog", + "total_error_findings": errs, + "decidable_ratio_at_generation": round(ratio, 2), + "entries": entries, + } + + def main(): ap = argparse.ArgumentParser( description="编号门禁:docs/编号规范.md §8 的 8 项校验(默认 warn-only)") ap.add_argument("--strict", action="store_true", - help="校验 1~6 的错误改为拦提交(默认 warn-only,不拦)") + help="增量拦截:台账(scripts/id_known_backlog.json)之外的新错误级问题 → 拦提交") + ap.add_argument("--write-backlog", action="store_true", + help="把当前全部错误级问题写成债务台账(关闸前的初始化动作)") + ap.add_argument("--prune-backlog", action="store_true", + help="从台账里收掉已还清的条目(只减不增),并回写") ap.add_argument("--verbose", action="store_true", help="每条附带修法") ap.add_argument("--top", type=int, default=12, help="每类校验打印的条数(默认 12)") ap.add_argument("--only", default="", help="只跑指定校验,如 --only 1,3,5") @@ -635,6 +680,39 @@ def main(): return rc ratio, errs = ck.report(args.top, parse_only(args.only)) + groups = err_groups(ck) + err_total = sum(groups.values()) + if args.only and (args.strict or args.write_backlog or args.prune_backlog): + print("[ERR] --only 是局部排查,不能与 --strict / 台账写入同用(门禁结论必须全量)", + file=sys.stderr) + return 2 + if args.write_backlog: + entries = [{"file": k[0], "code": k[1], "literal": k[2], "count": v} + for k, v in sorted(groups.items())] + BACKLOG_FILE.write_text( + json.dumps(backlog_doc(entries, err_total, ratio), ensure_ascii=False, indent=2) + "\n", + encoding="utf-8", newline="\n") + print("[OK] 债务台账已写 %s:%d 条指纹,覆盖 %d 处错误级问题" + % (BACKLOG_FILE.name, len(entries), err_total)) + return 0 + if args.prune_backlog: + led = load_backlog() + if led is None: + print("[ERR] 还没有台账,无从清理", file=sys.stderr) + return 2 + paid = [k for k in led if groups.get(k, 0) == 0] + grew = [(k, led[k], groups.get(k, 0)) for k in led if groups.get(k, 0) > led[k]] + kept = [{"file": k[0], "code": k[1], "literal": k[2], "count": groups[k]} + for k in sorted(led) if groups.get(k, 0) > 0] + BACKLOG_FILE.write_text( + json.dumps(backlog_doc(kept, err_total, ratio), ensure_ascii=False, indent=2) + "\n", + encoding="utf-8", newline="\n") + print("[OK] 台账已还清 %d 条,剩 %d 条(只减不增)" % (len(paid), len(kept))) + for k, was, now in grew[:10]: + print("[WARN] 台账内条目**变多了**(这属于新增债务,strict 会拦):%s 校验%d %s %d→%d" + % (k[0], k[1], k[2], was, now)) + return 0 + if args.update_baseline: base = reg.get("decidable_ratio_baseline") if base is not None and ratio + RATIO_TOL < base: @@ -672,12 +750,26 @@ def main(): print("\n[FAIL] 校验 8:可判定比例跌破基线 %.2f%% < %.2f%%(只许涨不许跌,容差 %.1fpp)" % (ratio, base, RATIO_TOL)) return 1 - if errs: + if err_total: if args.strict: - print("\n[FAIL] 编号门禁:%d 处错误级问题(--strict 拦提交)" % errs) - return 1 - print("\n[WARN] 编号 backlog:%d 处错误级问题,warn-only 不拦提交" - "(§8 上线节奏:清账后加 --strict)" % errs) + led = load_backlog() + if led is None: + print("\n[FAIL] --strict 但缺 scripts/id_known_backlog.json —— 拒绝退化成" + "「一次性拦死全部存量」(那样只会逼人 --no-verify)。" + "先跑 --write-backlog 生成台账(§8.4)", file=sys.stderr) + return 2 + new = {k: c - led.get(k, 0) for k, c in groups.items() if c > led.get(k, 0)} + if new: + print("\n[FAIL] 编号门禁·增量拦截:%d 类**台账之外**的错误级问题(新引入的债,§8.4)" + % len(new)) + for (rel, code, lit), n in sorted(new.items(), key=lambda kv: -kv[1])[:args.top]: + print(" +%d [校验%d] %s %s" % (n, code, rel, lit)) + print(" → 改引用/补登记处;确属该欠的债要在台账写 reason(默认禁止顺手加)") + return 1 + print("\n[OK] 增量拦截通过:无台账外新账(存量 %d 处按台账豁免,§8.4)" % err_total) + else: + print("\n[WARN] 编号 backlog:%d 处错误级问题,warn-only 不拦提交" + "(关闸方式见 §8.4:--strict + 债务台账)" % err_total) else: print("\n[OK] 校验 1~6 无错误") return 0 diff --git a/scripts/id_known_backlog.json b/scripts/id_known_backlog.json new file mode 100644 index 00000000..fc40a3e8 --- /dev/null +++ b/scripts/id_known_backlog.json @@ -0,0 +1,2049 @@ +{ + "schema": 1, + "note": "编号债务台账(docs/编号规范.md §8.4):--strict 只对**台账之外**的新错误级问题拦提交。台账只许减不许增——还清的用 --prune-backlog 收掉;确需新增一条必须写 reason 字段说明这笔债为什么该存在,默认禁止顺手加行(否则一周后台账就变成第二个 backlog)。指纹 = 文件 + 校验号 + 字面量,不含行号(行号会漂,用它台账天天假新增)。", + "generated_by": "scripts/check_ids.py --write-backlog", + "total_error_findings": 710, + "decidable_ratio_at_generation": 82.73, + "entries": [ + { + "file": ".dsh/skills/serial-assistant/scripts/serial_tool.py", + "code": 2, + "literal": "T1", + "count": 1 + }, + { + "file": ".dsh/skills/ui-verify/SKILL.md", + "code": 6, + "literal": "R-9", + "count": 1 + }, + { + "file": ".gitea/workflows/ci.yml", + "code": 2, + "literal": "S3", + "count": 3 + }, + { + "file": ".pre-commit-config.yaml", + "code": 6, + "literal": "D-2", + "count": 2 + }, + { + "file": ".pre-commit-config.yaml", + "code": 6, + "literal": "D-3", + "count": 1 + }, + { + "file": ".pre-commit-config.yaml", + "code": 6, + "literal": "D-7", + "count": 3 + }, + { + "file": ".pre-commit-config.yaml", + "code": 6, + "literal": "F-1", + "count": 1 + }, + { + "file": "App/algo/freq.c", + "code": 2, + "literal": "S2", + "count": 2 + }, + { + "file": "App/app/app_cfg.h", + "code": 6, + "literal": "P2-12", + "count": 1 + }, + { + "file": "App/cfg/cfg_file.c", + "code": 6, + "literal": "P0-1", + "count": 1 + }, + { + "file": "App/cfg/cfg_file.c", + "code": 6, + "literal": "P1-3", + "count": 1 + }, + { + "file": "App/cfg/cfg_file.c", + "code": 6, + "literal": "P2-1", + "count": 6 + }, + { + "file": "App/cfg/cfg_file.c", + "code": 6, + "literal": "P3-1", + "count": 1 + }, + { + "file": "App/cfg/cfg_file.h", + "code": 6, + "literal": "P1-3", + "count": 1 + }, + { + "file": "App/cfg/cfg_file_store_mcu.c", + "code": 6, + "literal": "P0-1", + "count": 2 + }, + { + "file": "App/cfg/cfg_file_store_mcu.c", + "code": 6, + "literal": "P3-2", + "count": 3 + }, + { + "file": "App/log/console_log.c", + "code": 2, + "literal": "gen-288", + "count": 3 + }, + { + "file": "App/log/sys_log_mcu.c", + "code": 6, + "literal": "P2-10", + "count": 3 + }, + { + "file": "App/log/sys_log_mcu.c", + "code": 6, + "literal": "P2-9", + "count": 4 + }, + { + "file": "App/task/adc_task.c", + "code": 2, + "literal": "Task #32", + "count": 8 + }, + { + "file": "App/task/adc_task.c", + "code": 6, + "literal": "P0-2", + "count": 2 + }, + { + "file": "App/task/adc_task.c", + "code": 6, + "literal": "P1-5", + "count": 4 + }, + { + "file": "App/task/adc_task.c", + "code": 6, + "literal": "P3-11", + "count": 1 + }, + { + "file": "App/task/adc_task.h", + "code": 2, + "literal": "Task #32", + "count": 2 + }, + { + "file": "App/task/adc_task.h", + "code": 6, + "literal": "P1-5", + "count": 2 + }, + { + "file": "App/task/default_task.c", + "code": 2, + "literal": "Task #32", + "count": 4 + }, + { + "file": "App/task/default_task.c", + "code": 6, + "literal": "P1-3", + "count": 1 + }, + { + "file": "App/task/default_task.c", + "code": 6, + "literal": "P2-9", + "count": 1 + }, + { + "file": "App/task/iec104_serv.c", + "code": 2, + "literal": "I-1", + "count": 1 + }, + { + "file": "App/task/net_task.c", + "code": 2, + "literal": "Task #32", + "count": 2 + }, + { + "file": "App/task/net_task.c", + "code": 6, + "literal": "P1-3", + "count": 1 + }, + { + "file": "App/task/net_task.c", + "code": 6, + "literal": "P1-6", + "count": 1 + }, + { + "file": "App/task/net_task.c", + "code": 6, + "literal": "P1-8", + "count": 5 + }, + { + "file": "App/task/net_task.c", + "code": 6, + "literal": "P2-11", + "count": 1 + }, + { + "file": "App/task/net_task.h", + "code": 6, + "literal": "P1-6", + "count": 1 + }, + { + "file": "App/task/rs485_task.c", + "code": 6, + "literal": "P3-11", + "count": 1 + }, + { + "file": "App/task/ui_task.c", + "code": 2, + "literal": "P1-4a", + "count": 2 + }, + { + "file": "App/task/ui_task.c", + "code": 2, + "literal": "Task #32", + "count": 3 + }, + { + "file": "App/util/task_prof.c", + "code": 2, + "literal": "Task #32", + "count": 1 + }, + { + "file": "App/util/task_prof.h", + "code": 2, + "literal": "Task #32", + "count": 1 + }, + { + "file": "Drivers/BSP/CH395F/ch395f.c", + "code": 6, + "literal": "P2-2", + "count": 5 + }, + { + "file": "Drivers/BSP/CH395F/ch395f.h", + "code": 6, + "literal": "P1-06", + "count": 1 + }, + { + "file": "Drivers/BSP/CH395F/ch395f.h", + "code": 6, + "literal": "P2-2", + "count": 1 + }, + { + "file": "Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c", + "code": 2, + "literal": "Trap 05", + "count": 1 + }, + { + "file": "Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.h", + "code": 2, + "literal": "Trap 05", + "count": 1 + }, + { + "file": "Drivers/BSP/GD5F2GQ5UE/nand_ftl.c", + "code": 2, + "literal": "Trap 05", + "count": 1 + }, + { + "file": "Drivers/BSP/GD5F2GQ5UE/nand_ftl.c", + "code": 2, + "literal": "Trap 07", + "count": 1 + }, + { + "file": "Drivers/BSP/NET/net_select.c", + "code": 6, + "literal": "P2-7", + "count": 2 + }, + { + "file": "Drivers/BSP/NET/net_socket.c", + "code": 6, + "literal": "P1-7", + "count": 1 + }, + { + "file": "Drivers/BSP/NETCFG/net_cfg.c", + "code": 6, + "literal": "P1-3", + "count": 1 + }, + { + "file": "Drivers/BSP/NETCFG/net_cfg.h", + "code": 6, + "literal": "P1-3", + "count": 1 + }, + { + "file": "Drivers/BSP/RS485/rs485.c", + "code": 6, + "literal": "P3-4", + "count": 1 + }, + { + "file": "Drivers/BSP/UI/ui_net_sink.c", + "code": 2, + "literal": "I-1", + "count": 2 + }, + { + "file": "Drivers/BSP/UI/ui_net_sink.c", + "code": 2, + "literal": "I-2", + "count": 3 + }, + { + "file": "Drivers/BSP/UI/ui_net_sink.c", + "code": 2, + "literal": "Task #32", + "count": 1 + }, + { + "file": "MDK-ARM/retracted_bench_20260922/README.txt", + "code": 2, + "literal": "Trap 21", + "count": 1 + }, + { + "file": "Src/freertos.c", + "code": 2, + "literal": "Task #32", + "count": 1 + }, + { + "file": "Src/freertos.c", + "code": 6, + "literal": "P1-5", + "count": 1 + }, + { + "file": "Src/freertos.c", + "code": 6, + "literal": "P1-6", + "count": 1 + }, + { + "file": "Src/freertos.c", + "code": 6, + "literal": "P2-13", + "count": 1 + }, + { + "file": "Src/main.c", + "code": 2, + "literal": "Task #32", + "count": 1 + }, + { + "file": "Src/main.c", + "code": 6, + "literal": "P1-5", + "count": 2 + }, + { + "file": "docs/CI/远程CI完整指南.md", + "code": 2, + "literal": "S3", + "count": 2 + }, + { + "file": "docs/CI/远程CI完整指南.md", + "code": 6, + "literal": "D-3", + "count": 1 + }, + { + "file": "docs/README.md", + "code": 2, + "literal": "T1", + "count": 1 + }, + { + "file": "docs/README.md", + "code": 2, + "literal": "Task #32", + "count": 1 + }, + { + "file": "docs/README.md", + "code": 6, + "literal": "D-3", + "count": 1 + }, + { + "file": "docs/README.md", + "code": 6, + "literal": "D-6", + "count": 4 + }, + { + "file": "docs/README.md", + "code": 6, + "literal": "D-7", + "count": 3 + }, + { + "file": "docs/UI设计/UI_自动化测试流程.md", + "code": 6, + "literal": "F-1", + "count": 1 + }, + { + "file": "docs/UI设计/UI_设计架构.md", + "code": 6, + "literal": "F-1", + "count": 1 + }, + { + "file": "docs/UI设计/内容页架构.md", + "code": 6, + "literal": "P1-3", + "count": 1 + }, + { + "file": "docs/UI设计/菜单页面设计.md", + "code": 2, + "literal": "陷阱 1", + "count": 1 + }, + { + "file": "docs/UI设计/菜单页面设计.md", + "code": 2, + "literal": "陷阱 3", + "count": 1 + }, + { + "file": "docs/产品需求/产品需求设计文档.md", + "code": 6, + "literal": "P0-1", + "count": 1 + }, + { + "file": "docs/代码规范/pre-commit使用说明.md", + "code": 2, + "literal": "T1", + "count": 1 + }, + { + "file": "docs/代码规范/pre-commit使用说明.md", + "code": 2, + "literal": "W1-0", + "count": 1 + }, + { + "file": "docs/代码规范/pre-commit使用说明.md", + "code": 6, + "literal": "D-2", + "count": 3 + }, + { + "file": "docs/代码规范/pre-commit使用说明.md", + "code": 6, + "literal": "D-3", + "count": 3 + }, + { + "file": "docs/代码规范/pre-commit使用说明.md", + "code": 6, + "literal": "D-7", + "count": 3 + }, + { + "file": "docs/任务规划/README.md", + "code": 2, + "literal": "W1-0", + "count": 2 + }, + { + "file": "docs/任务规划/README.md", + "code": 6, + "literal": "R-2", + "count": 3 + }, + { + "file": "docs/任务规划/README.md", + "code": 6, + "literal": "R-3", + "count": 3 + }, + { + "file": "docs/任务规划/README.md", + "code": 6, + "literal": "R-4", + "count": 3 + }, + { + "file": "docs/任务规划/README.md", + "code": 6, + "literal": "R-5", + "count": 1 + }, + { + "file": "docs/任务规划/README.md", + "code": 6, + "literal": "R-6", + "count": 3 + }, + { + "file": "docs/任务规划/README.md", + "code": 6, + "literal": "R-9", + "count": 3 + }, + { + "file": "docs/任务规划/登记簿.md", + "code": 2, + "literal": "gen 181", + "count": 1 + }, + { + "file": "docs/任务规划/登记簿.md", + "code": 2, + "literal": "gen-288", + "count": 1 + }, + { + "file": "docs/任务规划/登记簿.md", + "code": 6, + "literal": "F-1", + "count": 1 + }, + { + "file": "docs/任务规划/登记簿.md", + "code": 6, + "literal": "R-2", + "count": 1 + }, + { + "file": "docs/任务规划/登记簿.md", + "code": 6, + "literal": "R-3", + "count": 1 + }, + { + "file": "docs/任务规划/登记簿.md", + "code": 6, + "literal": "R-4", + "count": 1 + }, + { + "file": "docs/任务规划/登记簿.md", + "code": 6, + "literal": "R-6", + "count": 1 + }, + { + "file": "docs/任务规划/登记簿.md", + "code": 6, + "literal": "R-9", + "count": 2 + }, + { + "file": "docs/内存管理/RAM使用分析与优化方案.md", + "code": 2, + "literal": "S2", + "count": 1 + }, + { + "file": "docs/内存管理/RAM使用分析与优化方案.md", + "code": 2, + "literal": "S3", + "count": 2 + }, + { + "file": "docs/内存管理/RAM使用分析与优化方案.md", + "code": 6, + "literal": "P1-3", + "count": 1 + }, + { + "file": "docs/内存管理/RAM预算台账.md", + "code": 2, + "literal": "W1-0", + "count": 2 + }, + { + "file": "docs/内存管理/RAM预算台账.md", + "code": 6, + "literal": "R-2", + "count": 5 + }, + { + "file": "docs/内存管理/RAM预算台账.md", + "code": 6, + "literal": "R-9", + "count": 3 + }, + { + "file": "docs/内存管理/内存内容分配策略.md", + "code": 2, + "literal": "gen68", + "count": 2 + }, + { + "file": "docs/内存管理/内存内容分配策略.md", + "code": 6, + "literal": "R-4", + "count": 1 + }, + { + "file": "docs/内存管理/存储栈RAM优化调研.md", + "code": 3, + "literal": "TRAP-GD5F-05", + "count": 1 + }, + { + "file": "docs/内存管理/存储栈RAM优化调研.md", + "code": 6, + "literal": "P0-1", + "count": 3 + }, + { + "file": "docs/内存管理/存储栈RAM优化调研.md", + "code": 6, + "literal": "P0-2", + "count": 7 + }, + { + "file": "docs/内存管理/存储栈RAM优化调研.md", + "code": 6, + "literal": "P0-3", + "count": 3 + }, + { + "file": "docs/内存管理/存储栈RAM优化调研.md", + "code": 6, + "literal": "P1-4", + "count": 6 + }, + { + "file": "docs/内存管理/存储栈RAM优化调研.md", + "code": 6, + "literal": "P1-5", + "count": 3 + }, + { + "file": "docs/内存管理/存储栈RAM优化调研.md", + "code": 6, + "literal": "P2-6", + "count": 1 + }, + { + "file": "docs/内存管理/存储栈RAM优化调研.md", + "code": 6, + "literal": "P2-7", + "count": 1 + }, + { + "file": "docs/内存管理/存储栈RAM优化调研.md", + "code": 6, + "literal": "P2-8", + "count": 1 + }, + { + "file": "docs/子系统设计/ADC采样节拍设计说明.md", + "code": 2, + "literal": "Task #32", + "count": 6 + }, + { + "file": "docs/子系统设计/ADC采样节拍设计说明.md", + "code": 6, + "literal": "P0-1", + "count": 2 + }, + { + "file": "docs/子系统设计/ADC采样节拍设计说明.md", + "code": 6, + "literal": "P0-2", + "count": 2 + }, + { + "file": "docs/子系统设计/ADC采样节拍设计说明.md", + "code": 6, + "literal": "P1-5", + "count": 4 + }, + { + "file": "docs/子系统设计/IEC104上行设计说明.md", + "code": 2, + "literal": "I-1", + "count": 1 + }, + { + "file": "docs/子系统设计/控制台单写者日志设计说明.md", + "code": 2, + "literal": "gen-288", + "count": 2 + }, + { + "file": "docs/子系统设计/看门狗设计说明.md", + "code": 2, + "literal": "P1-4a", + "count": 1 + }, + { + "file": "docs/子系统设计/看门狗设计说明.md", + "code": 2, + "literal": "Task #32", + "count": 2 + }, + { + "file": "docs/子系统设计/看门狗设计说明.md", + "code": 2, + "literal": "gen-288", + "count": 1 + }, + { + "file": "docs/子系统设计/看门狗设计说明.md", + "code": 2, + "literal": "round 3", + "count": 1 + }, + { + "file": "docs/子系统设计/看门狗设计说明.md", + "code": 2, + "literal": "round 7", + "count": 2 + }, + { + "file": "docs/子系统设计/看门狗设计说明.md", + "code": 2, + "literal": "round 8", + "count": 1 + }, + { + "file": "docs/子系统设计/看门狗设计说明.md", + "code": 3, + "literal": "N-03", + "count": 2 + }, + { + "file": "docs/子系统设计/运行与自检记录设计说明.md", + "code": 2, + "literal": "S2", + "count": 1 + }, + { + "file": "docs/子系统设计/运行与自检记录设计说明.md", + "code": 2, + "literal": "S3", + "count": 1 + }, + { + "file": "docs/子系统设计/运行与自检记录设计说明.md", + "code": 6, + "literal": "P2-10", + "count": 1 + }, + { + "file": "docs/子系统设计/运行与自检记录设计说明.md", + "code": 6, + "literal": "R-1", + "count": 1 + }, + { + "file": "docs/子系统设计/运行与自检记录设计说明.md", + "code": 6, + "literal": "R-2", + "count": 1 + }, + { + "file": "docs/子系统设计/配置文件设计说明.md", + "code": 6, + "literal": "P0-1", + "count": 7 + }, + { + "file": "docs/子系统设计/配置文件设计说明.md", + "code": 6, + "literal": "P1-3", + "count": 1 + }, + { + "file": "docs/子系统设计/配置文件设计说明.md", + "code": 6, + "literal": "P1-5", + "count": 1 + }, + { + "file": "docs/文档规范.md", + "code": 6, + "literal": "D-6", + "count": 3 + }, + { + "file": "docs/文档规范.md", + "code": 6, + "literal": "D-7", + "count": 4 + }, + { + "file": "docs/架构设计/项目架构总览.md", + "code": 6, + "literal": "P2-13", + "count": 1 + }, + { + "file": "docs/测试说明/ADC输入层单元测试说明.md", + "code": 2, + "literal": "TC-ADCIN-01A", + "count": 1 + }, + { + "file": "docs/测试说明/ADC输入层单元测试说明.md", + "code": 2, + "literal": "TC-ADCIN-02A", + "count": 1 + }, + { + "file": "docs/测试说明/ADC输入层单元测试说明.md", + "code": 2, + "literal": "TC-ADCIN-02B", + "count": 1 + }, + { + "file": "docs/测试说明/ADC输入层单元测试说明.md", + "code": 2, + "literal": "TC-ADCIN-02C", + "count": 1 + }, + { + "file": "docs/测试说明/ADC输入层单元测试说明.md", + "code": 2, + "literal": "TC-ADCIN-03A", + "count": 1 + }, + { + "file": "docs/测试说明/ADC输入层单元测试说明.md", + "code": 2, + "literal": "TC-ADCIN-04A", + "count": 1 + }, + { + "file": "docs/测试说明/ADC输入层单元测试说明.md", + "code": 2, + "literal": "TC-ADCIN-04B", + "count": 1 + }, + { + "file": "docs/测试说明/ADC输入层单元测试说明.md", + "code": 2, + "literal": "TC-AI-03A", + "count": 1 + }, + { + "file": "docs/测试说明/CH395F_Test_Guide.md", + "code": 2, + "literal": "DP-01", + "count": 16 + }, + { + "file": "docs/测试说明/CH395F_Test_Guide.md", + "code": 2, + "literal": "DP-02", + "count": 5 + }, + { + "file": "docs/测试说明/CH395F_Test_Guide.md", + "code": 2, + "literal": "DP-03", + "count": 7 + }, + { + "file": "docs/测试说明/CH395F_Test_Guide.md", + "code": 2, + "literal": "DP-04", + "count": 13 + }, + { + "file": "docs/测试说明/CH395F_Test_Guide.md", + "code": 2, + "literal": "TC-302", + "count": 1 + }, + { + "file": "docs/测试说明/CH395F_Test_Guide.md", + "code": 2, + "literal": "TC-501", + "count": 1 + }, + { + "file": "docs/测试说明/GD5F2GQ5UE_Test_Guide.md", + "code": 2, + "literal": "TC-1003", + "count": 1 + }, + { + "file": "docs/测试说明/GD5F2GQ5UE_Test_Guide.md", + "code": 2, + "literal": "TC-206", + "count": 1 + }, + { + "file": "docs/测试说明/GD5F2GQ5UE_Test_Guide.md", + "code": 2, + "literal": "TC-704", + "count": 2 + }, + { + "file": "docs/测试说明/GD5F2GQ5UE_Test_Guide.md", + "code": 2, + "literal": "陷阱 01", + "count": 1 + }, + { + "file": "docs/测试说明/GD5F2GQ5UE_Test_Guide.md", + "code": 3, + "literal": "TRAP-GD5F-01", + "count": 1 + }, + { + "file": "docs/测试说明/GD5F2GQ5UE_Test_Guide.md", + "code": 3, + "literal": "TRAP-GD5F-06", + "count": 1 + }, + { + "file": "docs/测试说明/串口助手设计说明.md", + "code": 2, + "literal": "S2", + "count": 1 + }, + { + "file": "docs/测试说明/串口助手设计说明.md", + "code": 2, + "literal": "S3", + "count": 1 + }, + { + "file": "docs/测试说明/实机测试实施指南.md", + "code": 2, + "literal": "round 1", + "count": 3 + }, + { + "file": "docs/测试说明/实机测试实施指南.md", + "code": 2, + "literal": "round 3", + "count": 1 + }, + { + "file": "docs/测试说明/实机测试实施指南.md", + "code": 2, + "literal": "round 7", + "count": 2 + }, + { + "file": "docs/测试说明/实机测试实施指南.md", + "code": 3, + "literal": "N-03", + "count": 2 + }, + { + "file": "docs/测试说明/实机测试实施指南.md", + "code": 6, + "literal": "H-1", + "count": 1 + }, + { + "file": "docs/测试说明/实机测试实施指南.md", + "code": 6, + "literal": "H-7", + "count": 1 + }, + { + "file": "docs/测试说明/实机测试实施指南.md", + "code": 6, + "literal": "L-2", + "count": 1 + }, + { + "file": "docs/测试说明/实机测试实施指南.md", + "code": 6, + "literal": "L-4", + "count": 1 + }, + { + "file": "docs/测试说明/实机测试实施指南.md", + "code": 6, + "literal": "P0-1", + "count": 1 + }, + { + "file": "docs/测试说明/实机测试实施指南.md", + "code": 6, + "literal": "P1-8", + "count": 5 + }, + { + "file": "docs/测试说明/模拟器差距清单.md", + "code": 6, + "literal": "P0-1", + "count": 1 + }, + { + "file": "docs/测试说明/测试开发标准流程.md", + "code": 2, + "literal": "DP-01", + "count": 1 + }, + { + "file": "docs/测试说明/测试开发标准流程.md", + "code": 2, + "literal": "S2", + "count": 2 + }, + { + "file": "docs/测试说明/测试开发标准流程.md", + "code": 2, + "literal": "S3", + "count": 2 + }, + { + "file": "docs/测试说明/测试开发标准流程.md", + "code": 6, + "literal": "P1-6", + "count": 4 + }, + { + "file": "docs/测试说明/测试开发标准流程.md", + "code": 6, + "literal": "P1-9", + "count": 2 + }, + { + "file": "docs/测试说明/测试文档模板规范.md", + "code": 2, + "literal": "DP-01", + "count": 2 + }, + { + "file": "docs/测试说明/测试文档模板规范.md", + "code": 2, + "literal": "DP-02", + "count": 1 + }, + { + "file": "docs/测试说明/测试文档模板规范.md", + "code": 3, + "literal": "TC-XXX-001", + "count": 2 + }, + { + "file": "docs/测试说明/测试文档模板规范.md", + "code": 3, + "literal": "TM-NAND-01", + "count": 1 + }, + { + "file": "docs/测试说明/测试文档模板规范.md", + "code": 3, + "literal": "TM-XXX-01", + "count": 1 + }, + { + "file": "docs/测试说明/链路延迟测试说明.md", + "code": 2, + "literal": "S2", + "count": 2 + }, + { + "file": "docs/测试说明/链路延迟测试说明.md", + "code": 2, + "literal": "S3", + "count": 1 + }, + { + "file": "docs/环境与部署/并行任务工作树方案.md", + "code": 2, + "literal": "trap22", + "count": 1 + }, + { + "file": "docs/环境与部署/项目部署环境要求.md", + "code": 6, + "literal": "P2-12", + "count": 1 + }, + { + "file": "docs/网络/BSD_Socket_API_使用指南.md", + "code": 6, + "literal": "P1-3", + "count": 1 + }, + { + "file": "docs/网络/BSD_Socket_API_函数调用关系.md", + "code": 2, + "literal": "T1", + "count": 4 + }, + { + "file": "docs/网络/BSD_Socket_API_函数调用关系.md", + "code": 6, + "literal": "P1-7", + "count": 2 + }, + { + "file": "docs/网络/网络自愈架构设计.md", + "code": 2, + "literal": "T1", + "count": 1 + }, + { + "file": "docs/问题记录/CH395F_Trap_Records.md", + "code": 2, + "literal": "round 1", + "count": 1 + }, + { + "file": "docs/问题记录/GD5F2GQ5UE_Trap_Records.md", + "code": 2, + "literal": "Trap 01", + "count": 1 + }, + { + "file": "docs/问题记录/GD5F2GQ5UE_Trap_Records.md", + "code": 2, + "literal": "Trap 02", + "count": 1 + }, + { + "file": "docs/问题记录/GD5F2GQ5UE_Trap_Records.md", + "code": 2, + "literal": "Trap 03", + "count": 4 + }, + { + "file": "docs/问题记录/GD5F2GQ5UE_Trap_Records.md", + "code": 2, + "literal": "Trap 04", + "count": 2 + }, + { + "file": "docs/问题记录/GD5F2GQ5UE_Trap_Records.md", + "code": 2, + "literal": "Trap 05", + "count": 1 + }, + { + "file": "docs/问题记录/GD5F2GQ5UE_Trap_Records.md", + "code": 2, + "literal": "Trap 06", + "count": 2 + }, + { + "file": "docs/问题记录/GD5F2GQ5UE_Trap_Records.md", + "code": 2, + "literal": "Trap 07", + "count": 1 + }, + { + "file": "docs/问题记录/GD5F2GQ5UE_Trap_Records.md", + "code": 2, + "literal": "gen 45", + "count": 1 + }, + { + "file": "docs/问题记录/SD2506_Trap_Records.md", + "code": 2, + "literal": "陷阱 1", + "count": 1 + }, + { + "file": "docs/问题记录/项目审查与优化建议报告.md", + "code": 2, + "literal": "Trap 07", + "count": 1 + }, + { + "file": "docs/问题记录/项目审查与优化建议报告.md", + "code": 2, + "literal": "W1-0", + "count": 1 + }, + { + "file": "docs/问题记录/项目审查与优化建议报告.md", + "code": 6, + "literal": "P1-10", + "count": 3 + }, + { + "file": "docs/问题记录/项目审查与优化建议报告.md", + "code": 6, + "literal": "P2-10", + "count": 2 + }, + { + "file": "docs/问题记录/项目审查与优化建议报告.md", + "code": 6, + "literal": "P2-13", + "count": 1 + }, + { + "file": "docs/问题记录/项目审查与优化建议报告.md", + "code": 6, + "literal": "P2-14", + "count": 1 + }, + { + "file": "docs/问题记录/项目审查与优化建议报告.md", + "code": 6, + "literal": "P2-15", + "count": 1 + }, + { + "file": "docs/问题记录/项目审查与优化建议报告.md", + "code": 6, + "literal": "P2-5", + "count": 2 + }, + { + "file": "docs/问题记录/项目审查与优化建议报告.md", + "code": 6, + "literal": "P2-6", + "count": 1 + }, + { + "file": "docs/问题记录/项目审查与优化建议报告.md", + "code": 6, + "literal": "P2-8", + "count": 2 + }, + { + "file": "docs/问题记录/项目审查与优化建议报告.md", + "code": 6, + "literal": "P2-9", + "count": 2 + }, + { + "file": "scripts/README.md", + "code": 2, + "literal": "Trap 19", + "count": 1 + }, + { + "file": "scripts/README.md", + "code": 6, + "literal": "D-2", + "count": 1 + }, + { + "file": "scripts/README.md", + "code": 6, + "literal": "D-3", + "count": 1 + }, + { + "file": "scripts/README.md", + "code": 6, + "literal": "D-7", + "count": 1 + }, + { + "file": "scripts/check_doc_links.py", + "code": 6, + "literal": "D-3", + "count": 1 + }, + { + "file": "scripts/check_lv_conf_sync.py", + "code": 6, + "literal": "F-1", + "count": 1 + }, + { + "file": "scripts/check_mem_numbers.py", + "code": 6, + "literal": "D-7", + "count": 2 + }, + { + "file": "scripts/check_test_traceability.py", + "code": 2, + "literal": "TC-014", + "count": 1 + }, + { + "file": "scripts/check_test_traceability.py", + "code": 3, + "literal": "TC-XXX-003b", + "count": 1 + }, + { + "file": "scripts/ci_local.py", + "code": 2, + "literal": "S3", + "count": 2 + }, + { + "file": "scripts/gen_task_table.py", + "code": 6, + "literal": "D-2", + "count": 1 + }, + { + "file": "scripts/gen_task_table.py", + "code": 6, + "literal": "D-7", + "count": 1 + }, + { + "file": "scripts/ram_baseline.py", + "code": 2, + "literal": "W1-0", + "count": 1 + }, + { + "file": "scripts/ram_baseline.py", + "code": 6, + "literal": "R-9", + "count": 1 + }, + { + "file": "scripts/rename_ids.py", + "code": 2, + "literal": "S3", + "count": 2 + }, + { + "file": "scripts/rename_ids.py", + "code": 3, + "literal": "TC-PROTSET-11", + "count": 1 + }, + { + "file": "simulator/lv_conf.h", + "code": 6, + "literal": "F-2", + "count": 1 + }, + { + "file": "simulator/sim/cfg_file_store_sim.c", + "code": 6, + "literal": "P0-1", + "count": 1 + }, + { + "file": "simulator/tests/check_content_pages.py", + "code": 6, + "literal": "F-2", + "count": 1 + }, + { + "file": "simulator/tests/check_menu_rows.py", + "code": 6, + "literal": "F-2", + "count": 1 + }, + { + "file": "test/board/ch395f_test_task.c", + "code": 2, + "literal": "DP-04", + "count": 3 + }, + { + "file": "test/board/ch395f_test_task.c", + "code": 2, + "literal": "TC-1501", + "count": 1 + }, + { + "file": "test/board/ch395f_test_task.c", + "code": 2, + "literal": "TC-1502", + "count": 1 + }, + { + "file": "test/board/ch395f_test_task.c", + "code": 2, + "literal": "TC-1502b", + "count": 1 + }, + { + "file": "test/board/ch395f_test_task.c", + "code": 2, + "literal": "TC-1503", + "count": 1 + }, + { + "file": "test/board/ch395f_test_task.c", + "code": 2, + "literal": "TC-201", + "count": 1 + }, + { + "file": "test/board/ch395f_test_task.c", + "code": 2, + "literal": "TC-203", + "count": 1 + }, + { + "file": "test/board/ch395f_test_task.c", + "code": 2, + "literal": "TC-301", + "count": 2 + }, + { + "file": "test/board/ch395f_test_task.c", + "code": 2, + "literal": "TC-302", + "count": 2 + }, + { + "file": "test/board/ch395f_test_task.c", + "code": 6, + "literal": "P1-01", + "count": 5 + }, + { + "file": "test/board/ch395f_test_task.c", + "code": 6, + "literal": "P1-02", + "count": 3 + }, + { + "file": "test/board/ch395f_test_task.c", + "code": 6, + "literal": "P1-03", + "count": 5 + }, + { + "file": "test/board/ch395f_test_task.c", + "code": 6, + "literal": "P1-04", + "count": 3 + }, + { + "file": "test/board/ch395f_test_task.c", + "code": 6, + "literal": "P1-05", + "count": 3 + }, + { + "file": "test/board/ch395f_test_task.c", + "code": 6, + "literal": "P1-06", + "count": 4 + }, + { + "file": "test/board/ch395f_test_task.c", + "code": 6, + "literal": "P1-07", + "count": 3 + }, + { + "file": "test/board/ch395f_test_task.c", + "code": 6, + "literal": "P1-08", + "count": 3 + }, + { + "file": "test/board/ch395f_test_task.c", + "code": 6, + "literal": "P1-09", + "count": 5 + }, + { + "file": "test/board/gd5f_test_task.c", + "code": 2, + "literal": "Trap 05", + "count": 1 + }, + { + "file": "test/board/gd5f_test_task.c", + "code": 3, + "literal": "TC-GD5F-1101", + "count": 3 + }, + { + "file": "test/board/gd5f_test_task.c", + "code": 3, + "literal": "TC-GD5F-1102", + "count": 1 + }, + { + "file": "test/board/net_latency_test.c", + "code": 6, + "literal": "P1-06", + "count": 1 + }, + { + "file": "test/board/net_test_task.c", + "code": 6, + "literal": "P1-9", + "count": 1 + }, + { + "file": "test/board/storage_test_task.c", + "code": 2, + "literal": "Trap 05", + "count": 1 + }, + { + "file": "test/board/test_config.h", + "code": 6, + "literal": "P2-13", + "count": 1 + }, + { + "file": "test/host/adc_input/adc_input_test.c", + "code": 2, + "literal": "TC-ADCIN-003B", + "count": 1 + }, + { + "file": "test/host/adc_input/adc_input_test.c", + "code": 2, + "literal": "TC-ADCIN-003C", + "count": 1 + }, + { + "file": "test/host/adc_input/adc_input_test.c", + "code": 2, + "literal": "TC-ADCIN-003D", + "count": 1 + }, + { + "file": "test/host/adc_input/adc_input_test.c", + "code": 2, + "literal": "TC-ADCIN-005B", + "count": 1 + }, + { + "file": "test/host/adc_input/adc_input_test.c", + "code": 2, + "literal": "TC-ADCIN-01A", + "count": 1 + }, + { + "file": "test/host/adc_input/adc_input_test.c", + "code": 2, + "literal": "TC-ADCIN-02A", + "count": 1 + }, + { + "file": "test/host/adc_input/adc_input_test.c", + "code": 2, + "literal": "TC-ADCIN-02B", + "count": 1 + }, + { + "file": "test/host/adc_input/adc_input_test.c", + "code": 2, + "literal": "TC-ADCIN-02C", + "count": 2 + }, + { + "file": "test/host/adc_input/adc_input_test.c", + "code": 2, + "literal": "TC-ADCIN-03A", + "count": 2 + }, + { + "file": "test/host/adc_input/adc_input_test.c", + "code": 2, + "literal": "TC-ADCIN-03B", + "count": 1 + }, + { + "file": "test/host/adc_input/adc_input_test.c", + "code": 2, + "literal": "TC-ADCIN-03C", + "count": 1 + }, + { + "file": "test/host/adc_input/adc_input_test.c", + "code": 2, + "literal": "TC-ADCIN-03D", + "count": 1 + }, + { + "file": "test/host/adc_input/adc_input_test.c", + "code": 2, + "literal": "TC-ADCIN-03E", + "count": 1 + }, + { + "file": "test/host/adc_input/adc_input_test.c", + "code": 2, + "literal": "TC-ADCIN-04A", + "count": 1 + }, + { + "file": "test/host/adc_input/adc_input_test.c", + "code": 2, + "literal": "TC-ADCIN-04B", + "count": 1 + }, + { + "file": "test/host/adc_input/adc_input_test.c", + "code": 2, + "literal": "TC-ADCIN-074B", + "count": 1 + }, + { + "file": "test/host/adc_input/adc_input_test.c", + "code": 2, + "literal": "TC-ADCIN-09A", + "count": 1 + }, + { + "file": "test/host/adc_input/adc_input_test.c", + "code": 3, + "literal": "TC-ADCIN-031", + "count": 1 + }, + { + "file": "test/host/adc_input/adc_input_test.c", + "code": 3, + "literal": "TC-ADCIN-032", + "count": 1 + }, + { + "file": "test/host/adc_input/adc_input_test.c", + "code": 3, + "literal": "TC-ADCIN-036", + "count": 1 + }, + { + "file": "test/host/adc_input/adc_input_test.c", + "code": 3, + "literal": "TC-ADCIN-037", + "count": 1 + }, + { + "file": "test/host/adc_input/adc_input_test.c", + "code": 3, + "literal": "TC-ADCIN-038", + "count": 1 + }, + { + "file": "test/host/adc_input/adc_input_test.c", + "code": 3, + "literal": "TC-ADCIN-071", + "count": 1 + }, + { + "file": "test/host/adc_input/adc_input_test.c", + "code": 3, + "literal": "TC-ADCIN-072", + "count": 1 + }, + { + "file": "test/host/adc_input/adc_input_test.c", + "code": 3, + "literal": "TC-ADCIN-073", + "count": 1 + }, + { + "file": "test/host/adc_input/adc_input_test.c", + "code": 3, + "literal": "TC-ADCIN-074", + "count": 1 + }, + { + "file": "test/host/adc_input/adc_input_test.c", + "code": 3, + "literal": "TC-ADCIN-075", + "count": 1 + }, + { + "file": "test/host/adc_input/adc_input_test.c", + "code": 3, + "literal": "TC-ADCIN-076", + "count": 1 + }, + { + "file": "test/host/adc_input/adc_input_test.c", + "code": 3, + "literal": "TC-ADCIN-078", + "count": 1 + }, + { + "file": "test/host/adc_input/adc_input_test.c", + "code": 3, + "literal": "TC-ADCIN-081", + "count": 1 + }, + { + "file": "test/host/adc_input/adc_input_test.c", + "code": 3, + "literal": "TC-ADCIN-082", + "count": 1 + }, + { + "file": "test/host/adc_input/adc_input_test.c", + "code": 3, + "literal": "TC-ADCIN-083", + "count": 1 + }, + { + "file": "test/host/adc_input/adc_input_test.c", + "code": 3, + "literal": "TC-ADCIN-084", + "count": 1 + }, + { + "file": "test/host/adc_input/adc_input_test.c", + "code": 3, + "literal": "TC-ADCIN-085", + "count": 1 + }, + { + "file": "test/host/adc_input/adc_input_test.c", + "code": 3, + "literal": "TC-ADCIN-087", + "count": 1 + }, + { + "file": "test/host/adc_input/adc_input_test.c", + "code": 3, + "literal": "TC-ADCIN-088", + "count": 1 + }, + { + "file": "test/host/adc_input/adc_input_test.c", + "code": 3, + "literal": "TC-ADCIN-089", + "count": 1 + }, + { + "file": "test/host/adc_input/adc_input_test.c", + "code": 3, + "literal": "TC-ADCIN-091", + "count": 1 + }, + { + "file": "test/host/adc_input/adc_input_test.c", + "code": 3, + "literal": "TC-ADCIN-092", + "count": 1 + }, + { + "file": "test/host/adc_input/adc_input_test.c", + "code": 3, + "literal": "TC-ADCIN-093", + "count": 1 + }, + { + "file": "test/host/cfg_file/cfg_file_test.c", + "code": 2, + "literal": "TC-010", + "count": 1 + }, + { + "file": "test/host/cfg_file/cfg_file_test.c", + "code": 2, + "literal": "TC-014", + "count": 2 + }, + { + "file": "test/host/cfg_file/cfg_file_test.c", + "code": 3, + "literal": "TC-CONFIG-024", + "count": 2 + }, + { + "file": "test/host/cfg_file/cfg_file_test.c", + "code": 3, + "literal": "TC-CONFIG-044", + "count": 2 + }, + { + "file": "test/host/cfg_file/cfg_file_test.c", + "code": 3, + "literal": "TC-CONFIG-052", + "count": 1 + }, + { + "file": "test/host/cfg_file/cfg_file_test.c", + "code": 6, + "literal": "P2-1", + "count": 2 + }, + { + "file": "test/host/ch395f_socket_test.py", + "code": 2, + "literal": "TC-301", + "count": 9 + }, + { + "file": "test/host/ch395f_socket_test.py", + "code": 2, + "literal": "TC-302", + "count": 9 + }, + { + "file": "test/host/ch395f_socket_test.py", + "code": 2, + "literal": "TC-602", + "count": 2 + }, + { + "file": "test/host/e11_keepalive_probe.py", + "code": 2, + "literal": "T1", + "count": 2 + }, + { + "file": "test/host/ftp_auth_bench.py", + "code": 2, + "literal": "T1", + "count": 3 + }, + { + "file": "test/host/iec104/iec104_test.c", + "code": 2, + "literal": "TC-001", + "count": 4 + }, + { + "file": "test/host/iec104/iec104_test.c", + "code": 2, + "literal": "TC-002", + "count": 3 + }, + { + "file": "test/host/iec104/iec104_test.c", + "code": 2, + "literal": "TC-003", + "count": 5 + }, + { + "file": "test/host/iec104/iec104_test.c", + "code": 2, + "literal": "TC-004", + "count": 2 + }, + { + "file": "test/host/iec104/iec104_test.c", + "code": 2, + "literal": "TC-005", + "count": 2 + }, + { + "file": "test/host/iec104/iec104_test.c", + "code": 2, + "literal": "TC-006", + "count": 11 + }, + { + "file": "test/host/iec104/iec104_test.c", + "code": 2, + "literal": "TC-007", + "count": 7 + }, + { + "file": "test/host/iec104/iec104_test.c", + "code": 2, + "literal": "TC-008", + "count": 2 + }, + { + "file": "test/host/iec104/iec104_test.c", + "code": 2, + "literal": "TC-009", + "count": 3 + }, + { + "file": "test/host/iec104/iec104_test.c", + "code": 2, + "literal": "TC-010", + "count": 2 + }, + { + "file": "test/host/iec104/iec104_test.c", + "code": 2, + "literal": "TC-011", + "count": 2 + }, + { + "file": "test/host/iec104/iec104_test.c", + "code": 2, + "literal": "TC-012", + "count": 5 + }, + { + "file": "test/host/iec104/iec104_test.c", + "code": 2, + "literal": "TC-013", + "count": 5 + }, + { + "file": "test/host/iec104/iec104_test.c", + "code": 2, + "literal": "TC-014", + "count": 7 + }, + { + "file": "test/host/iec104/iec104_test.c", + "code": 2, + "literal": "TC-015", + "count": 4 + }, + { + "file": "test/host/iec104/iec104_test.c", + "code": 2, + "literal": "TC-016", + "count": 3 + }, + { + "file": "test/host/iec104/iec104_test.c", + "code": 2, + "literal": "TC-017", + "count": 2 + }, + { + "file": "test/host/iec104/iec104_test.c", + "code": 2, + "literal": "TC-018", + "count": 3 + }, + { + "file": "test/host/iec104/iec104_test.c", + "code": 2, + "literal": "TC-019", + "count": 1 + }, + { + "file": "test/host/iec104/iec104_test.c", + "code": 2, + "literal": "TC-020", + "count": 7 + }, + { + "file": "test/host/iec104/iec104_test.c", + "code": 2, + "literal": "TC-021", + "count": 2 + }, + { + "file": "test/host/iec104/iec104_test.c", + "code": 2, + "literal": "TC-022", + "count": 3 + }, + { + "file": "test/host/iec104/iec104_test.c", + "code": 2, + "literal": "TC-023", + "count": 2 + }, + { + "file": "test/host/iec104/iec104_test.c", + "code": 2, + "literal": "TC-024", + "count": 11 + }, + { + "file": "test/host/soe/soe_test.c", + "code": 2, + "literal": "TC-001", + "count": 9 + }, + { + "file": "test/host/soe/soe_test.c", + "code": 2, + "literal": "TC-002", + "count": 4 + }, + { + "file": "test/host/soe/soe_test.c", + "code": 2, + "literal": "TC-003", + "count": 6 + }, + { + "file": "test/host/soe/soe_test.c", + "code": 2, + "literal": "TC-004", + "count": 3 + }, + { + "file": "test/host/soe/soe_test.c", + "code": 2, + "literal": "TC-005", + "count": 4 + }, + { + "file": "test/host/soe/soe_test.c", + "code": 2, + "literal": "TC-006", + "count": 4 + }, + { + "file": "test/host/soe/soe_test.c", + "code": 2, + "literal": "TC-007", + "count": 2 + }, + { + "file": "test/run_all_suites.py", + "code": 6, + "literal": "P1-10", + "count": 1 + }, + { + "file": "test/run_all_suites.py", + "code": 6, + "literal": "P1-9", + "count": 1 + }, + { + "file": "tools/netlist_semantics/gen_kb.py", + "code": 2, + "literal": "T1", + "count": 7 + }, + { + "file": "tools/netlist_semantics/netlist_sem.py", + "code": 2, + "literal": "T1", + "count": 1 + }, + { + "file": "tools/netlist_semantics/pinout_kb.json", + "code": 2, + "literal": "T1", + "count": 7 + } + ] +} diff --git a/scripts/id_registry.json b/scripts/id_registry.json index 895a6d9f..b5a8a8b3 100644 --- a/scripts/id_registry.json +++ b/scripts/id_registry.json @@ -57,7 +57,8 @@ "scripts/check_ids.py", ".dsh/skills/*/scripts/state/", ".dsh/n31_neg_inject_gen217.log", - ".dsh/n31_neg_inject_gen221_form5.log" + ".dsh/n31_neg_inject_gen221_form5.log", + "scripts/id_known_backlog.json" ], "excluded_suffixes": [ ".svg",