Commit Graph

12 Commits

Author SHA1 Message Date
wandering1 6505cef9df feat(门禁): coding-standard 加 CODE-RULE-20 禁 C 库堆分配(销 §4.8 空白 ②)
规则:在**掩码后**的文本上匹配 malloc/calloc/realloc/strdup/strndup/
free/aligned_alloc 调用。三条判据都是踩过坑之后定的——
- 大小写敏感:pvPortMalloc / vPortFree(唯一允许的配对)不会误报;
- 词边界 \b:dhara_nand_is_free(、buf_alloc( 这类同形后缀不误报;
- 用掩码:注释与字符串字面量里写 malloc 不报(规范示例就踩过这种)。
覆盖名比 AGENTS 列的五枚多带上 strndup / aligned_alloc——同族同类,
漏一个就等于留后门。

出处不在规范 V1.0,在平台约束:MicroLIB 的 C 堆由 startup_stm32f407xx.s
的 Heap_Size EQU 0x200 只有 512 B,KB 级分配必返 NULL,而模拟器(宿主
CRT 堆)完全正常、**照不出来**——配置引擎 2026-09-18 那次堆分配纠偏与
lftpd 的 malloc 隐患都是**先上线才发现**的那类,靠评审等于没管。

落地前按 门禁说明/coding-standard.md §8 的纪律先全库普查:钩子范围内
C/H 共 151 个文件,命中**只有** simulator/sim/cfg_file_store_sim.c 两行,
即 cfg_store_alloc/cfg_store_free = **平台分配后端的宿主侧实现**(设计依据
写在 docs/子系统设计/配置文件设计说明.md 的"MCU 端 = pvPortMalloc、
模拟器端 = 宿主 CRT")。所以零基线、直接硬拦截;豁免用脚本里的
HEAP_ALLOC_ALLOWLIST(**文件路径 + 函数名**双条件),刻意不做目录级豁免:
下次谁要碰 C 堆就得往这张表加一行,评审看得见。

自证:临时样例文件里 malloc/calloc/free 各报一处,pvPortMalloc/vPortFree/
buf_alloc(、注释、字符串五种陷阱形态全部不误报;
pre-commit run coding-standard --all-files → **Passed**(= 全库零存量)。

顺带修三处口径不一致:
- 规范 V1.0 §6.1 的示例自己写着 malloc/free(通用 C 模板遗留)→ 已在示例
  下加"本仓例外,别照抄"批注,事实源指向 AGENTS.md 平台约束;
- docs/门禁说明/mem-budget.md 里"这条纪律只靠 AGENTS 铁律与评审"已过期 →
  更正为由 CODE-RULE-20 机器拦截;
- AGENTS.md 平台约束条加"已机器拦截 + 唯一豁免"一句;scripts/README.md
  补登 check_test_coverage.py(上一个提交漏登记)。

另:本次一并修好上一处编辑事故——报告 §4.8 曾被我的脚本调用截成半句
(只落第一行、丢掉 malloc 那半句),已重写为"两处空白均已闭合"。

自查:pre-commit run --files(9 个改动文件)适用项全 Passed;
check_doc_links.py --all = 35 处,与主干同数(本分支贡献 0);
check_ids.py --strict 通过(裸编号 P0-1 改平实说法,避免记成新账);
9 个文件 BOM/CR/U+FFFD/行尾与 HEAD 逐项一致。本轮零 .c/.h 改动,未跑
@build、未占 build/bench 锁;分支已 rebase 到 v2-on-ui,覆盖率脚本全量
回归仍 16/16、line=2552/2893 不变。
2026-10-23 23:44:46 +08:00
wandering1 6822726b2c docs(门禁说明): 手册 §2 收敛为通用机制与查号表,逐项详解归一到 23 篇
用户一句"现在门禁都在干什么,我一概不知"引出的收尾。原手册 §2 有 27 个逐钩子小节,只回答
"拦了什么、怎么配",回答不了"什么时候会骗我";docs/门禁说明/ 已把逐项详解(含"限制与盲区"
一节)建好,本笔做收敛:同一事实只留一处(docs/文档规范.md 的要求)。

**先搬后删**(否则收敛等于丢事实):旧 §2 里独有条目逐篇折回,共 18 处插入、15 篇受益。折回的
东西包括:六套主机单测的来历与用例规模(13/36/82/46/32/149 断言,含 nand-port 的"与旧算法
对照")与"改动公共骨架 unit_test_harness.py 会同时触发 16 个钩子";UI 页面**两层注册**(构建
注册 vs 框架注册:枚举 + s_defs[] 描述符表)与"豁免不整目录一刀切";lv-conf-sync 首次落地清掉
26 个 LVGL 9.3 不存在的选项、3 处重复定义、10 项隐式开关显式化,以及 ALLOW_DIFF 端专属白名单
与必须穿过 lv_conf_internal.h 里那层 KCONFIG 包裹;cubemx-survival 的 16 项清单、断言前先剥
C 注释(本仓注释刻意引用历史代码,不剥就恒定误报)、旧手册"自造标记区"建议与看门狗文档实测
教训之间的优先级;id-check 顺带收编 check_test_traceability.py、裸形同字母多义属**显式承认的
盲区**、--update-baseline 只许涨;layer-deps 的注入自证与报错时三条修法(注入回调 / 上层递数据
/ 才谈 ALLOW);coding-standard **nand_ftl.* 也在排除清单**(我先前那篇漏了);test-suite-switch
的剥注释判定与派生宏白名单;mem-budget 两类软提醒不拦、退出码 2 是解析失败不是通过;doc-links
的排除目录与状态词 ±40 字符距离;task-table 改栈三步;gitlint 报错样例;no-mojibake 的修复路径。

**顺带抓到旧文档两处错**(记进文档,不悄悄改):一是 check-added-large-files 的阈值旧手册写
"单个文件 > 1MB",按本机安装的钩子源码实测是 --maxkb 默认 **500**(500 KB)——已更正,并把
"本目录任何默认值都以实测或安装的钩子源码为准"写进 end-of-file-fixer 当反面教材;二是
**ui-golden 在旧手册里连小节都没有**,只活在配置注释里:除了"有基线不等于有门禁",这是另一种
失踪——有钩子、没文档。

手册 §2 改写为三节:迁移说明 / **旧编号 → 新文档 查号表**(历史引用靠它读,旧号按"冻结历史不
回改"保留)/ **跨钩子通用机制**:两阶段与换机必须重装 hooks 才带 commit-msg、stash 陷阱、
always: true 已废、改写型与只读型豁免不对称、增量拦截三段式且刻意没有 --write、没有 .map 是
"跳过"不是"通过"、改配置的验收是看目标钩子出现在输出里且不是 Skipped、新增门禁三步必须做
注入自证且"限制与盲区"不许留空,另有快速自查入口。手册 707 行 → 273 行。

引用**按内容**重指(只核编号存在与否不够,同号小节会被当本文自引用静默放过):编号规范、
scripts/README(顺带更正那里过时的 warn-only 说法,早已关闸为增量拦截)、RAM 使用分析与优化
方案、测试开发标准流程、lvgl-simulator skill、AGENTS 文档表(拆成"每门禁一篇详解"与"通用
机制"两行)、.pre-commit-config.yaml 头注释、docs/README.md 描述、手册自身 §5.5 与 §6 的两处
内部引用。另:表格里的裸节号会被 doc-links 判成本文自引用,查号表统一写成不带 § 的形态。

写说明过程又被自家门禁拦一次:gitlint 篇里引用报错样例时写了两个规则号字面量,被判形态不合规
→ 改成中文描述,没有往台账里塞 reason 解决。

验证:纯文档与注释改动,不动代码,Program Size 不变,故不跑 @build/@test;
check_doc_links --all --sections-strict **171 篇 0 问题**;id-check 增量拦截通过;
pre-commit run **RC=0 / 13 项 Passed**;28 个改动文件字节卫生 **0 异常**(无 BOM、无 CR、
无 U+FFFD、均 LF、无行尾空白)。
2026-10-23 11:44:21 +08:00
wandering1 52976bdec3 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 条、变更记录
2026-10-21 12:32:13 +08:00
wandering1 301c3e5183 feat(门禁): 编号门禁 id-check 落地(36→37 钩子)+ 批 1 编号单词化改名
新增门禁本体
- scripts/check_ids.py:实现 docs/编号规范.md §8 八项校验;默认 warn-only,
  唯一硬拦项是「可判定比例跌破基线」(防回退的本体)
- scripts/id_registry.json:66 个前缀族,逐项来自 §4 总表 + 全库实测游标,
  偏差一律写进 cursor_note,不凭记忆编造
- scripts/id_aliases.json:旧号 → 新号 / 作废标记(照搬 section_aliases.json 范式)
- 顺带收编 check_test_traceability.py:正则补齐大写后缀与无模块码形态,
  比对范围扩到 test/host 与 7 篇「单元测试说明.md」,另加 --board-only 回退旧口径

批 1 改名(用户授权解禁「不改写存量号」)
- 代码规范条款 S1~S19 → CODE-RULE-nn:78 处 / 2 文件
- UI 像素回归状态 S0~S7 → MENU-STATE-nn:61 处 / 3 文件(冻结在 07)
- 两族属主登记处 = 脚本自身的规则表 / STATES 表,文档只作引用方
- 新增 scripts/rename_ids.py(§7.3 规划脚本):映射表驱动、显式 scope、默认干跑、
  自动写 scoped 别名,跳过 [示例]/[计划] 行与变更记录表,按原字节读写保 BOM 行尾
- 已应用映射表存档 scripts/rename_maps/batch1.json 作审计轨迹

有牙实测(证明门禁不是空转)
- 注入 Z-99 / 裸形 / 悬空 / 越游标 / 未紧邻 / 跨文档重复定义 六例,
  分别被校验 1/2/3/5/6/4 点名,--strict 退出码 1;临时档删除后工作树干净

验证与同步
- 可判定比例基线 82.3% → 82.7%(已 --update-baseline 入档);错误级 1312 → 1291
- ci_local.py 全绿(L0 + L0.5 共 1104 断言);ui-golden Passed;
  check_doc_links.py --all 无法判定 0
- 未改任何 C/H 源文件,故本次不需 @build
- 文档:AGENTS.md 与 pre-commit使用说明.md 计数 36→37 并新增 §2.25 详解;
  编号规范 §4.1 补两行、§8.1 落地记录、§8.2 规范与仓库偏差、§8.3 迁移批次记录
2026-10-21 09:33:54 +08:00
wandering1 c077e9a481 merge: 远程 CI 分支 v2-on-ui-ci 合入 v2-on-ui
CI / L0.5 主机侧单测 (MSVC) (push) Has been cancelled
CI / L0 静态门禁 (pre-commit) (push) Has been cancelled
将 origin/v2-on-ui-ci(13 个提交:远程 CI 文档独立成 docs/CI/、
runner 保活/日志编码/gitlint 空转修复、ci_local L0b 等)合入开发主线。

冲突 5 处,按「两侧意图取并集」解决:
- AGENTS.md / docs/README.md:保留主线 待处理内容.md→任务规划/ 重构,
  并入 CI 分支的 docs/CI/ 索引行与更新日志
- 测试开发标准流程.md §9.1:取 CI 分支,引用改指
  ../CI/远程CI完整指南.md 对应小节
- docs/待处理内容.md:接受主线删除,已重构为 docs/任务规划/
- docs/环境与部署/CI配置指南.md:接受 CI 分支删除,已并入 docs/CI/

合并引入的 doc-links 失效已修(doc-links 合并态走 --sections-strict,
自引用解析失败即硬错误):
- CI 指南 §0.0 标题把 ⚠️ 移到编号后(编号须打头才解析得出)
- CI 指南对 待处理内容.md 的引用改指 docs/任务规划/登记簿.md T-7 条
- CI 指南并入来源《测试开发标准流程》§9.4 / §9.2 改为全路径限定
- 测试开发标准流程 §9.4:§0.2/§2/§2.4/§4.1.3 原与 CI 文档路径间隔
  超过链式继承上限 40 字符,改为紧跟路径并拆分明细句
- 测试开发标准流程 §9.1:步骤级细节引用同样全路径限定到 CI 指南
2026-10-12 19:42:24 +08:00
wandering1 ba40cc0d20 远程 CI 文档独立成 docs/CI/:两篇重叠指南合并为一篇,AGENTS.md 压成一行指针
动因:远程 CI 只跑在本机一台 runner(win-stm32-ci)上,其他机器与项目都不涉及,
但内容散在 4 处约 2000 行——两篇高度重叠的指南躺在「环境与部署」里与换机核对清单
并列,AGENTS.md 提交门禁节还塞了 4 条 runner 运维经验,导致每次会话都被这些机器
专属细节干扰。

结构:新建 docs/CI/,README.md 作唯一入口(适用范围 + 章节速查 + 常用命令),
远程CI完整指南.md 为合并稿。

- 合并:CI配置指南 477 行 + Gitea_Runner部署指南 917 行 → 一篇 1300 行;骨架内容
  逐行比对核实无丢失(仅章节重编号与相对链接按新位置改写),重复段按"留新版"去重,
  独有内容全部搬入(下载/config.yaml 字段语义/不能用 Windows 服务的根因/内网 action
  三种处置/check_env 自检/TL;DR/排障表 13 条独有行/MySQL 直查核验)
- 再分配:测试流程 §9.2 两个 job 的步骤细节并入指南 §5.5、§9.4 部署前置表并入 §0.2;
  测试流程 §9 只留测试分层视角(覆盖哪些层、触发与 paths-ignore、本地等价、
  "CI 不替代本地门禁")
- AGENTS.md:4 条 CI 经验(看门狗 / gitlint stage / UTF-16LE / CI 概览)压成 1 行指针
- 引用同步 6 个文件:docs/README 目录树与索引、项目部署环境要求 3 处、本地工具路径
  环境变量方案、待处理内容、scripts/README(补登 3 个 CI 脚本并标注为本机专属)

验证:check_doc_links.py --all 125 篇 0 问题;pre-commit run --all-files 17 项全 Passed。
两篇旧文档以 git rm 删除(历史仍在 git 中);各文档变更记录的历史行按仓库惯例不改写,
只新增 2026-10-12 行。
2026-10-12 14:03:44 +08:00
wandering1 d1e6bb4ba7 W5波+N-19收口:FTP鉴权落地、Trap25三连定案修复(N-30)、N-20/N-23/N-26
N-19 FTP 鉴权:
- lftpd_auth(USER/PASS 状态机 + 连续5次失败锁60s)+ SHA-256
  (user||pwd) 口令哈希;config.ini [ftp] 段 user/pwd_hash/write,
  出厂 admin/admin 在用有启动告警;lftpd_log.c 删除并入 lftpd_auth
- ftp_cfg 配置读写;台架 ftp_auth_bench.py 13/13

N-30 / Trap 25(CH395F_Trap_Records.md 四次定案全记录):
- 修复1 closed-with-data accept:客户端发完正常 FIN 后芯片按
  FUN_PARA(0x09) §5.52② 保留 Socket+RX 缓冲,旧代码把 CLOSED 一律
  relisten 自毁缓冲 → STOR 必挂 425;改为接受"已关但可读"连接排空
- 修复2 丢 CONNECT 中断探针 net_lost_connect_probe + last_peer_port
  幽灵甄别(拆链窗口握手完成但中断丢失,双信源去抖补 accept)
- 修复3 send_list/send_nlst 批量单发:背靠背 ~60B 小段毒化芯片 TX
  (芯片报 SEND_OK 但对端全丢),整份目录一次性写入
- 证伪存档:固定沉降/Socket 轮换冷却/listen 门控(台架 v7 矩阵)
- 台架工具 test/board/ch395f_reuse_bench.{c,h} + host 脚本存档
  (不注册编译;实验分支 n30-chip-bench 保留)

N-20:Error_Handler 死循环降级(记录+复位路径)
N-23:scripts/check_registration.py 双端注册反向校验(pre-commit)
N-26:GD5F NAND 直 DMA 调用方缓冲窗口断言

验证:BUILD_OK 0/0;ftp_regression 连跑 4 轮 11/11(修复前
LIST#4/#7 100% 挂、STOR#2 曾 100% 425);ftp_auth_bench 13/13;
@test 启动标记 PASS;ci_local L0+L0.5 全过;doc-links 通过。
登记簿 N-30 已销项。
2026-10-11 18:50:24 +08:00
wandering1 f0300761ae 串口采集/测试去重:删 tools/serial_tool 与 test/host run_boot_test/verify_log 副本,引用改指 .dsh/skills 串口 skill 2026-10-10 15:13:23 +08:00
wandering1 33a4aa4945 本地工具路径DTU_*环境变量改造落地:10处调用点去硬编码+变量优先解析,本机全链路验证通过,文档同步收口,requirements补pre-commit 2026-10-02 22:14:49 +08:00
wandering1 e90486524d CI:Gitea Actions 落地 L0+L0.5(补 T-6)
新增 .gitea/workflows/ci.yml:push/PR 触发两个 Windows job——
l0-gates 跑 pre-commit --all-files(无 Keil .map 时自适应跳过 mem-numbers),
l05-host-unit-tests 遍历 test/host/**/run_unit_test.py(缺 MSVC 则告警降级跳过)。
刻意不跑 @build(需 Keil 授权);L1/L2/L3 需真机+ST-LINK,不上 CI。

新增 scripts/ci_local.py:本地跑与 CI 等价的门禁(自动选用装了 pre-commit
的解释器;.map 自适应;退出码 0/1/2 与 CI 对齐),供提交前自查与 runner 就绪前过渡。

文档同步:测试开发标准流程 §9(CI 章节)/§1/§4.1、待处理内容 T-6 销项、
项目部署环境要求 §2.11(runner 前置)、pre-commit 使用说明 §1、scripts/README.md、AGENTS.md。

验证:scripts/ci_local.py rc=0(L0 14 钩子全过 + L0.5 39/39)。
2026-10-01 10:19:38 +08:00
wandering1 2055de0303 测试:落地测试架构改进 T-1~T-5(套件开关门禁/汇总行校验/通用 harness/公共断言宏/多套件编排)
背景:L0.5 主机侧单测落地后复审测试架构,给出 6 条改进意见(P0~P3),
登记进 docs/待处理内容.md「测试与验证基础设施」后逐条实施。

- T-1(P0) 测试套件开关门禁:新增 scripts/check_test_suite.py + pre-commit 钩子
  test-suite-switch,默认要求产品构建(全部 TEST_SUITE_* 注释),跑套件回归用
  --allow-test-build / ALLOW_TEST_BUILD=1 显式放行。顺带把 test_config.h 中长期
  开启的 TEST_SUITE_CH395F 改回注释(仓库此前躺着的是测试固件)。
- T-2(P1) verify_log.py 增加 --require-suite-summary:要求
  "=== <名称>: N/M PASSED (failed=0) ===" 且 N>0,堵住"套件没跑到汇总行/
  断言数为 0 仍判 PASS"的盲区;run_boot_test.py 同名参数透传。不传参向后兼容。
- T-3(P1) 抽取通用 harness test/host/common/unit_test_harness.py(工具链探测/
  INCLUDE-LIB 拼接/wd4819/GBK 解码/退出码契约);watchdog 运行器 170→55 行,只声明 TestBuild。
- T-4(P2) 新增 test/board/test_common.h 集中断言内核(TEST_CHECK_IMPL/TEST_REPORT_IMPL),
  4 套件各用一行宏绑定自身统计变量(保持 g_xxx_stats 独立、防跨套件串数)。
  刻意不 include dbg_log.h——否则冻结 DBG_TAG 默认值触发 #47-D 重定义警告。
- T-5(P2) 新增 test/run_all_suites.py 多套件回归编排,try/finally 无条件还原套件开关。

验证:@build 产品构建 0 错 0 警;4 套件逐一构建均 0/0;看门狗单测 39/39 PASS;
pre-commit 14 钩子全通过;编排脚本 dry-run/开关切换/异常还原均实测通过。
2026-10-01 07:28:57 +08:00
wandering1 39bd06adea 为自建代码目录补齐 README,建立目录级导航体系
- 新增 26 份目录 README:App/(+log,task,util,protocol)、Drivers/BSP/(+8子系统)、
  Src/、Inc/、scripts/、tools/(+6子工具)、test/、MDK-ARM/、simulator/(+sim,tests)
- 每份含:定位、文件清单表、关键约束/陷阱、指向 docs 权威文档
- 第三方库与生成代码目录排除(CMSIS/HAL/Middlewares/Lib/SDL2)
- docs/文档规范.md 新增 §1.1b 代码目录 README 约定;根 README 目录结构加入说明
2026-09-26 12:25:36 +08:00