Commit Graph

728 Commits

Author SHA1 Message Date
wandering1 15111eaec3 docs(硬件): 外设引脚口径由 V0.0 更正为 V0.1
README 外设接口表与部署环境要求 3.2 节长期停留在 V0.0 引脚,
与 Inc/main.h(CubeMX 已迁 V0.1)不符。按 main.h 与 V0.1 网表
报告 §4.1 更正三处:

- TPAFE 控制组 7 线:PD3/PD4/PD7 + PF13/14/15 改为
  PC6 FRSTDATA / PC7 BUSY(EXTI) / PC8 RD / PC9 CONVST /
  PA8 OS2 / PA11 OS1 / PA12 OS0(原表漏 FRSTDATA 且 OS 顺序反)
- RS-485:UART5(PC12/PD2/PD0)改为 UART4(PC10/PC11/PA15),
  依据 app_main.c 的 rs485_init(&g_rs485, &huart4, ...)
- LED1/LED2 驱动脚:PC4/PC5 改为 PC5/PB0(PC4 让位给 ADC17),
  并补网名与丝印 LED(n+4) 倒序提示

产品需求设计文档 4.2 节随之删除该「文档遗留」标注(已闭环)。
README 补 RTC/SWD 两行,两处均加「口径 = V0.1」与权威来源。
2026-10-28 09:11:07 +08:00
wandering1 4974321f2d docs(产品需求): 新增 9.4~9.12 缺口逐项明细
把 9 章从"缺口清单"补成"逐项明细":每个定值、每个点、每个模块
差在哪,以及怎么算做完。

- 定值:40 项去向对账(覆盖参考 35 + 本地 5),差额更正为 214 项;
  23 单元差额表 + 已覆盖 35 项逐项对照 + 未覆盖 163 项清单
- 遥测:31 点逐点对照,缺 22 点按依赖分三批
- 开入开出:138 = 软遥信 104 + 硬件 27 + 双点 6 + 多态 1;
  31 开出 = 出口 11 + 信号 20
- 动作事件:33 条(421~453)逐条对照,覆盖 9 条
- 保护元件:模块级 45 -> 8,37 个缺失模块逐个给出后果与依赖,
  差额由 +35 更正为 +37
- 录波:14 项硬指标与复刻所需四件东西
- 记录体系:13 类队列容量表,覆盖 8 类
- 规约栈:12 种逐种链路与工作量特征,四层排期
- 新增 9.12 复刻完成判据(12 条可验证判据)
2026-10-28 09:01:10 +08:00
wandering1 f10869f048 docs(产品需求): 改为 1:1 复刻口径并补参考源码实测清单
参考工程 Scatter_P_HV03.01_SV01.01 的源码常量表是唯一需求清单,
不再引用其分析文档(实测有两处不准:元件 89 vs 实为 45、
定值约 260 vs 实为 249)。

- 2.4 范围反转为参考能力全集,只允许 5 项不可移植项落在范围外
- 2.5 重写为 1:1 复刻基线:19 项能力清单、104 八段地址表、
  定值 23 单元分布、45 元件九类归集、规约全集、差异归因
- 更正 104 段基址笔误:参考 Rly_IEC104.h 为 1 起编,
  遥测 0x4001、遥控 0x6001(旧文档写 4000H+ / 6000H+)
- 9 重写为复刻进度与路线图,缺口分阻塞型与规模型两表
- 5.9~5.15 补全采集链与 104 需求,6.8 点表摘要补差额说明
2026-10-28 08:55:21 +08:00
wandering1 5e0c702369 docs(文档规范): 第 2 节补一行 run_code 正文写法口径——落点选在乱码行之后,唯一锚点可断言
第 2 节的表原来只讲编码、换行、行尾空白、文件尾、乱码五件事,
把长中文正文写进 run_code 程序体这一路一直没有口径,同一族写法事故在一个会话里复发八次。
现象分三类:混用引号或正文里塞进 ASCII 双引号,报 Expected 逗号 got ident;
反引号与 shell 专有量(状态数组、退出码变量)混进程序体同样解析失败;
字段名位置误用全角冒号,也是同一类语法错。
而解析一失败,同一程序里其后的写文件与提交全部静默零落地,只留下一个从未存在的临时文件,
下一轮复用它就以 ENOENT 或提交 128 退出收场,返工成本整轮落在这条链上。
现补第 6 件:整个程序只用一种 ASCII 引号定界,中文引号一律「」,反引号字符现取再拼,
正文逐行进数组,落盘后打印 bom、crlf、超 80 字符行数与占位残留四个卫生数复核。
本笔只加这一行,零编号增删,门禁口径与钩子计数都不动。
2026-10-28 08:17:01 +08:00
wandering1 aa9f4cbfe4 docs(id-check): 批次六收口复测——在册旧号活引用归零,账面不动基线
把两类别名(retired-to-phrase 与 void)当探针做全库复扫,口径同《门禁说明》的 id-check 篇第 9 节:
排除 excluded_paths、门禁自身语料与变更记录行。
命中 22 个文件 / 86 行,真编号活引用 0 处;余下命中面全部落在变更记录行(第 4.3 节不回改)、
元器件位号与 Socket 状态组合(第 4.4 节判非编号)以及属主文档的历史对照列。
账面决定:不重打《编号规范》第 8.1 节两根护栏基线——那些数随在飞改动漂移,属各自批次的收口;把某天的实测值钉进正文表格,
等于自造一条会过期的断言,本轮第一次尝试就撞了一次。
当日实测与命中清单写入 ci-artifacts 下的仓库外口径台账(被 .gitignore 挡住、不进语料),正文只留结论与口径。
本笔零编号增删、零语料增删:可判定比例只许涨、不可判定绝对数只减不增,两根基线均未下调。
改动面:《编号规范》第 9 节批次表补第六行收口记录;《门禁说明》id-check 篇追加当日变更行,自证本轮未并行派单。
同篇第 7.7 节的当日构成表按冻结证据原样保留,不随今日数字重打。
提交前按《门禁说明》README 第 2 节的实跑口径统一走一遍只读检查(文档链接、编号门禁、BOM 漂移、乱码、
git diff --check)。
风险与回滚:纯文档改动,不涉及构建与真机;单提交可逆(git revert),无需数据迁移。
2026-10-28 08:14:48 +08:00
wandering1 a583c36a88 docs(门禁说明): 补充 nested-comment 的触发面口径
本次只改一处中文 Markdown,未触碰 C 源码、头文件与 Keil 工程档案。
因此不跑 @build;提交门禁按文档口径只跑 doc-links 与 pre-commit 命中的钩子。
只暂存这一个 Markdown 文件,让 51 个钩子按 files 与 types 只命中文档相关那几根。
工作区另有两份文档的在飞改动与两份未跟踪脚本,一律不纳入本次提交。
提交正文由 UTF-8 无 BOM 文件承载,经 git commit -F 传入仓库,不走 -m 参数。
原因是 Windows 终端代码页会对命令行参数转码,中文可能变成不可逆的乱码。
正文按每行不超过 80 字符书写(.gitlint 口径),标题不超过 100 字符,中间空行。
正文行不以 # 开头,否则会被默认的注释清理规则删掉;行尾统一 LF 且无尾随空格。
Markdown 改动用精确子串替换落盘,保留文件原有 BOM 状态与行尾,不整文件重写。
落库前后都按字节统计 EF BF BD,结果必须为 0,不信终端与编辑器的渲染结果。
2026-10-28 08:05:21 +08:00
wandering1 97049a4bf0 docs(plan): 采集链与上送链台架联调分工
新增 docs/任务规划/分工说明-20261028-采集链与上送链联调.md(45 行):
只分工不改行为。A 线走采集链 L1→L2→L2.5,B 线走上送链 L2.5→104/UI,
两条线各自验收后合并,不交叉编辑对方文件。

- A 线交付:App/algo/README.md 补「快照时序」一节;adc_input 主机单测
  增帧序号回绕与双缓冲半帧两个用例;ADC采样节拍说明 §5 按实测节拍回填。
- B 线交付:meas 双区快照的单写者与多读者一致性说明;ui_data 补陈旧
  代次(generation)用例;新增 .c 时双端注册 Keil 工程与 CMakeLists。
- 禁区写进正文:CODE-RULE-20 禁 C 库堆分配、V0.1 禁跨转换器做相位与
  功率运算、layer-deps 不许 BSP 反依赖 App、UI 源文件带 BOM 须原样补回。
- 验收表:台架一次烧录须 -Rst -Run 并回读校验(No difference found),
  串口日志不得出现 [ERR]——四个 Fault 的崩溃日志都以它开头。

随笔修一处:正文第 31 行举例引用的 §4.2 在目标文档里已不存在,改指现有
小节 §10.1,否则 doc-links 门禁拦提交(编码 BOM、LF 与乱码均无变化)。
本笔只动这一份文档,代码与门禁配置零改动;上一笔 94b0d790 的页面接线与
任务卡号清退不在本笔内,其未做的六页真机判据已登记在登记簿 §7。
另记一笔待办:文中写的 MDK-ARM/STM32F4-Base.uvprojx 与实际工程文件名
(STM32F407-Demo.uvprojx)不符,留给该线负责人校正,本笔不代改。
2026-10-28 07:30:05 +08:00
wandering1 94b0d79026 feat(ui)+chore(docs): UI 补齐清单清空;数据可信销项与「卡」号清退
本笔含两组收尾工作(同一工作区内交错在 6 个共享文档/门禁配置里,
拆开会产生"文档声称的页数与树里黄金数不一致"的中间提交,故合为一笔):

一、UI 补齐(清单清空)
- 新建 6 个内容页模块:ui_page_accident / oper / alarm / start / yk
  复用 ui_w_records 共享组件(分页、空态"无记录"、按实例读盘缓存),
  记录层与五个写入点已由道F task-10 / 道G task-12 落地,本批只补页面;
  ui_page_runreport 为 13 行 2 页只读统计,四个数逐个挂范围标签
  (自电池周期 / 本次开机),boot_ready=0 显 "--" 不显 0。
- 数据面:ui_data_info_t 尾部追加 9 字段,ui_data_feed 用
  boot_stats_get() + iec104_serv_get_stats() 纯搬运;模拟器填确定值假数据
  (差异登记 docs/测试说明/模拟器差距清单.md §2.3 两行)。
- 接线:菜单树 6 叶绑 #page=,绑定叶 22→28、UI_PAGE_MAP_COUNT=28;
  字库 185→218 字 / 280→313 字形;双端注册 uvprojx +30、CMakeLists +6。
- 回归:内容页黄金 53→60(含 runreport_p2 真拍第 2 页),文本断言
  425 正向 / 36 反向;存量 53 张逐字节零漂移;记录 5 页各用独立空目录
  (模拟器把操作留痕写进 cwd 的 sim_oper.log,共用 tmp 会让空态拍不到)。

二、数据可信销项 + 「数据可信」任务卡号整族清退
- 删除已闭环的"已知电压注入验证"行与闭环结论块(证据在
  docs/硬件平台/ADC通道映射说明.md §8.1 与
  docs/测试说明/ADC前端注入验证流程.md §5~§7),§5 标识列改语义短语。
- 卡 0/0b/1~12 共 14 个号全仓 288 站点 / 56 文件清退成语义短语,
  代码注释、测试、门禁配置与文档一并改;换算表入 docs/编号规范.md §9.3。
  这一族是中文前缀,不进 check_ids 语料,刻意不入 id_aliases.json。

验证(实测)
- @build 0 错 0 警:Code=236456 RO=28124 RW=1876 ZI=137084;
  RAM +464 B(RW +304 / ZI +160),RW_IRAM1 62.2% / RW_CCM 87.9%,
  体积同码凭证与 RAM 台账已回填。
- check_menu_rows 8 状态 rc=0(池 5368/5448 常量未动);
  check_content_pages 60 页 rc=0;check_font_charset / registration /
  coding-standard / bom-drift / mojibake / doc-links --all / layer-deps /
  nested-comment 全 rc=0;check_ids --strict 无错误;主机单测
  ui_data 295 / boot_stats 21 / sys_log_mcu 141 / soe 32 / soe_store 27。

未做(不是遗漏)
- 六页真机判据(真记录翻页、掉电保持、清除后归零、boot_count 自增、
  拔 RTC 电池落 RESTARTED、IWDG 复位落 rst_cause、主站连一次 conn_up+1)
  已登记 docs/任务规划/登记簿.md §7;模拟器结构上照不到。
- docs/产品需求/产品需求设计文档.md 属另一条在飞改动,本笔不含;
  其中我已同步 6 处现状数字(28 叶 / 60 页 / 218 字),随该笔入库。
2026-10-28 07:23:16 +08:00
wandering1 8f7c141a0b docs(data-trust): 卡 0 注入验证闭环——标 ✅ 保留行,不按"完成即删"
卡 0(已知电压注入验证)2026-10-27 台架六项判据全 PASS,但**不删行**。
`数据可信.md` 卷首明文规定:卡 0 被 `App/task/adc_task.c` 的 v3.3 修订行与
`adc:` 行注释引用为口径出处("「数据可信」卡 0 注入验证的唯一连续读出口"),
删行会让代码头注释失去出处——这是"完成即删"在该文件的既定例外。

- 状态图例新增 ✅ 已闭环,限定"仅限被代码头注释指称的卡,保留行不删";
  §5 标题同步注明例外。
- 卷首"只剩三项"改为"只剩两项"(0b / 12),并说明卡 0 为何保留。
- §5 表:卡 0 状态 ⬜ → ✅;表下补"闭环结论"块(零点 0~5 码、R²=0.9999997、
  斜率 6544.2 码/V 偏差 −0.14 %、映射一一对应、极性对称性 ≤0.34 %、
  frames 1000 Hz),并记两项残差(最小二乘残差与 IB 零点贴上限)。
- §3 M4 行:① 已达成(原"① 与 ⑤ 待卡 0"),只剩 ⑤ 的台架面待卡 12。
- §2.6 首帧 ~1000 码的疑问结案:实测零点 0~5 码,首帧是上电瞬态,
  且 TPAFE ~11450 / STM32 ~1000 是两个转换器各自的零位。
- §6 顺序图与斜率规则:卡 0 标 ✅;补记实测偏差 −0.14 % 未触发规则,
  并说明该规则此次的真实价值是反向排除 2:1 分压(若分压斜率会掉到 ~3277)。
- §7 已定案:注入点修正为**串联电阻子板侧(`AINn` / `U5` 排针,③ 段的端子侧)**,
  原"在 ADC 引脚侧"作废——`U5` 排针才是可安全接触的最低一级。
- §8 风险表:ROM 默认系数风险解除(理论 LSB 被实测支持),
  加压烧板行改为"卡 0 已按 ≤2 V 执行完毕,端子级额定值仍须等 0b"。
- `ADC前端注入验证流程.md` §5.6 第 3 条:把"删行不留记录"改为记录实际处置。
2026-10-27 21:35:46 +08:00
wandering1 87615b2e99 docs(adc): 补节奏判据(注入前后 1000 Hz),删步骤 3 并重排编号
节奏:注入前(20:58 开机)与注入后(21:29)各取两行相隔 10 s 的
frames= 心跳,两边都是 Δ9998 码 / 约 10.0 s ≈ 1000.1 Hz,
idle=0、adc1_rc=0、adc1_err=0。卡 0 判据 5 的口径正是「注入前后」
帧计数仍严格 1000 Hz,故达标。adc1_gap/tgap/skip 为开机以来累计值,
10 s 内只增 3/2/1(约 0.03 %),属正常漏检量级。

至此六项判据全部 PASS:零点、线性、斜率、映射、极性、节奏。

删除 §5.4 步骤 3(逐通道映射):步骤 1 零点本身就是逐路独立激励,
短接哪路就看那路塌不塌,与「注入哪路只动哪路」是同一件事,重复做
没有增量信息。删除的唯一代价(原方案还含「其余七路仍在零点附近」
的串扰检查,而步骤 1 时其余七路浮空且本身在漂)已压进第 6 节判据表
的「映射」行括注,不单独占一节。

重排编号:5.5→5.4、5.6→5.5、5.7→5.6;步骤名同步 步骤4→3、5→4、
6→5,使「§5.N = 步骤 N-1」的对应关系恢复;第 4 节读数出口表里
「步骤 5 的节奏判据」同步改为「步骤 4」。全仓无其它文档引用本文
步骤号(已 grep 确认)。
2026-10-27 21:30:38 +08:00
wandering1 6b72b7c64f docs(adc): 前端注入验证实测结果——零点/线性/斜率/映射/极性五项 PASS
2026-10-27 台架首次完成直流注入验证,结果全部达标:

零点(8 路短接 AGND):0~5 码,折算 TPAFE ≤4.6 mV、STM32 ≤4.0 mV,
远小于零点补偿上限 ADC_CAL_B_MAX(8192)。IB 最贴边(2~5 码,上限 5),
余量最小,日后若变大先查 R49 / AIN9 那侧。

三点线性(UA,TPAFE):0.300/1.001/2.004 V 对应 1954/6547/13106 码。
最小二乘 R² = 0.9999997,斜率 6544.2 码/V(期望 6553.6,偏差 -0.14 %),
截距 -7.2 码(约 -1.1 mV)。残差 -2.0/+3.5/-1.4 码,无系统性弯曲。
这是「③ 段变比 = 1:1」在台架上的第一次直接证据。

极性(TPAFE 三路):-1.0 V 点 -6566/-6568/-6566,相对 -6554 偏
0.18~0.21 %;对称性偏差 0.27~0.34 %(判据 2 %)。补码符号位解释正确。

逐通道映射:原 5.4 步骤 3 已并入步骤 1,不再单独执行——步骤 1 本身就是
逐路独立激励,与「注入哪路只动哪路」是同一件事。已记录唯一代价:串扰
未单独证(步骤 1 时其余七路浮空且本身在漂,小幅串扰看不出来),
日后若怀疑串扰再恢复本节。

步骤 5 节奏本轮未取数(现场只读了 adc: 行,没记 frames=),记「待补」,
不算 PASS。故 docs/任务规划/数据可信.md 卡 0 判据 5 仍未闭环,本次
不销项。

另:6 判据汇总表新增「2026-10-27 实测」列与「总体结论」段。
2026-10-27 21:26:21 +08:00
wandering1 03721aafc4 docs: 新增 ADC 采样陷阱台账(TRAP-ADC-01/02)
把 2026-10-27 排查出的两个 ADC 采样陷阱沉淀成正式台账,按
docs/编号规范.md 的 TRAP-ADC-<nn> 编号,属主文档
docs/问题记录/ADC_Trap_Records.md。

TRAP-ADC-01:ADC 使能后闲置数秒才挂 DMA,导致 DMA 乒乓缓冲整体
+2 格相位旋转(槽 i 装的是 rank ((i+1) mod 9)+1)。全程无任何
编译或运行错误,只是数据整体错位两格,表象与「映射表写错」完全
一致,历史上据此误判过三轮。

条目重点记了那条判读陷阱:adcr[CH_i] == adcb[i] 成立不能证明通道
映射正确——它只证明拷贝循环是恒等映射,缓冲整体旋转时拷贝照样
恒等。判映射只能靠按通道号索引的独立真值(无 DMA 单通道读)。
附 9 行同开机对照证据表、5 种固件形态的 A/B 对照、修复方式、
回归判据与未证部分(微架构为何恰好丢 2 拍仍未证)。

TRAP-ADC-02:RTOS 运行期校准被 TIM3 TRGO 打断,adc1_calibrate()
返回 0xFFFF 超时哨兵。记了指纹判读要点(truth=65535 且 min 大于
max 是哨兵,不是满量程)与修法(校准期间屏蔽 EXTEN)。

关联登记三处:
- docs/README.md 7.3 问题记录表新增一行
- 设计文档 4.5 节加反向链接到 TRAP-ADC-01(代码 -> 设计 -> 台账)
- scripts/id_registry.json 的 TRAP 族 cursor_note 补 ADC 域 01~02

纯文档改动,不涉构建。
2026-10-27 20:55:04 +08:00
wandering1 859be6975c docs(adc): TPAFE 零点判据由 ≤10 放宽到 ≤30 码,并附实测依据
首次实测(2026-10-27)TPAFE 三路短接 AGND 后残差 UA -14 / UN -15 /
IA -13 码,约 2 mV,已超出原判据 <=10 码(约 1.5 mV)。

原 <=10 是定判据时按经验拍的,没有实测依据,比实测噪声还紧,
按它判必然失败。按 16 位 / 10 V 跨度算,2 mV 只有 0.02% FS,
属正常零点残余,故 TPAFE 档放宽到 <=30 码(约 4.6 mV)。

保留兜底:残差若继续增大(>30 码)说明前端确有真实失调
(R32 侧接地断、TPAFE 失调),那时必须回前端查,不得再放宽。
STM32 档 <=5 码不变(其短接列尚未取得可归属的实测值)。

同步四处:
- 测试说明/ADC前端注入验证流程.md 第 4 节判据说明(写明放宽理由
  与不可再放宽的边界)
- 同文档 5.2 节记录表 UA / UN / IA 三行判据列
- 同文档第 6 节判据汇总
- 任务规划/数据可信.md 卡 0 判据 3

固件里没有硬编码该判据(ADC_CAL_B_MAX=8192 是标定接受上限,无关),
故本次只改文档,不涉构建。
2026-10-27 20:49:23 +08:00
wandering1 1166ab1c2e fix(adc): 挂 DMA 前关闭 ADC,消除乒乓缓冲 +2 格相位旋转
问题:ADC1 在 MX_ADC1_Init() 里使能,而 DMA 在 app_main_init() 步骤
4b 才挂载,中间隔着 GD5F 全片 BBT 扫描(数秒)。台架同一次开机内用
无 DMA 单通道逐路取真值、与 DMA 路径对照,得 9/9 完美置换:乒乓缓冲
从 rank 3 开始搬,槽 i 装的是 rank ((i+1) mod 9)+1,整体错开 2 格。
表象是"接地 AIN2、UB 却读到别的通道的值",极易误判为映射表写错或
注入点标签不对。

修法:新增 adc1_disable()(Src/adc.c 的 USER CODE BEGIN 1),在
app_main_init() 步骤 4b-pre 调用,把 ADC 置为关闭态,使能动作交给
HAL_ADC_Start_DMA() 内部完成(它自己 __HAL_ADC_ENABLE + 等 Tstab
约 20 us,紧接着开 CR2.DMA 并启流),使能与搬运之间不留可观测间隔。
顺序不可调换:本调用必须严格早于 adc_input_init()。

台架验证:在 MX_ADC1_Init() 末尾关闭 4/4 次、在 4b-pre 调本 API
3/3 次,均 UB=0;同开机对照差值 <=4 码(修前 7/7 次 UB=783~786)。

文档:ADC采样节拍设计说明.md 新增 4.5 节(9 行证据表、判据陷阱、
根因与修法)与设计铁律第 8 条。

台账:Flash 261,764 -> 261,928 B(+164,新增函数),RAM 无变化;
CubeMX 存活审计基线重建(adc1-calibration-impl / adc1-dma-link
两项漂移均属本次有意改动,锚点已逐条复核在位)。
2026-10-27 20:42:06 +08:00
wandering1 e6d3e5a1be docs: 零点步骤补「rail 位图判短接是否到位」
只看某一瞬间的 adc: 行判断不了短接是否真的接触上——探针虚接时读数
停在半路,看起来像"接了地却没塌"。cal: 行末尾的 rail 是本次开机以来
"连续 20 ms 贴码值轨"的锁存位图,虚接锁存不上,才是权威判据。

2026-10-27 实测就靠它分清:UB/IB/IC 短接成功(rail=0x062),而 IN
从没到过地(bit7 缺席,读数稳定停在 610 码)。
2026-10-27 18:50:47 +08:00
wandering1 105422cfef docs: 零点记录表增「端子侧节点」列
表里只有通道名,现场还得翻回 §3 才知道要短哪个焊盘。把端子侧节点
(`AINn` + U5 脚位)并进记录表,一行内齐活。

节点值逐字取自 §3 注入点清单,8 路已交叉校验一致;同时说明该列就是
本步要短接的焊盘,别按通道名猜位置。
2026-10-27 18:35:05 +08:00
wandering1 69d70af4cf docs: 零点记录表改为与 adc 日志同序,补实测数据
台架首次实测暴露一处抄数陷阱:adc: 日志列序是 UA UB UC UN IA
IB IC IN,而记录表按语义分组排成 UA UN IA / UB UC IB IC IN。
照日志从左往右抄进表格从上往下,UN/IA 就填成了 STM32 的 ~1000、
UB/UC 填成了 TPAFE 的 ~11450 —— 而 UN/IA 属 TPAFE、UB/UC 属
STM32,这两个量级在物理上不可能,看起来像"数据全错"。

- 记录表行序改为与 adc: 日志完全一致,并加"转换器"列,量级对不上
  时一眼能看出来
- 表前加警示,把这次踩坑的经过写成具体例子(不写"注意顺序"这种
  空话,写清错在哪、错成什么样)
- 补"怎么抄短接后的数":只抄该路那一列,别贴整行;塌到 0 的不是
  你以为那一路,属映射问题转 §5.4,不是零点问题
- 补一句"短接后读到 0 是短接到位,不是取数失败"
- 记 2026-10-27 首次实测空载值(按日志列序归位):UA 11429 /
  UB 1044 / UC 954 / UN 11453 / IA 11451 / IB 1040 / IC 1062 /
  IN 980,与 18:04 烧录后开机日志一致

§8 已知坑按属主决定删除,不再保留。
2026-10-27 18:33:18 +08:00
wandering1 00f9958cbb docs: ADC 注入流程记录表并入各步,删 §9 与变更记录
原来"§5 步骤"只给判据、表格集中在 §9,台架现场要来回翻页;
现在每步末尾就是该步的填表处,边做边填。

- §5.2 零点:参考表与记录表合成一张,8 路逐行留空
- §5.3 三点线性:目标/实测/码值/反算 + 两片转换器期望码同表
- §5.4 逐通道映射:8 行,含"是否符合预期"列
- §5.5 极性:三路 × 正负两点 + 对称性偏差
- 删 §9「记录表」整节与「变更记录」小节,章节回到 1~8
- §4 与 §5.4 里指向 §9 / 附录表的引用改为"本节记录表"
- docs/README.md 目录描述同步为"每步自带现场记录表"

变更记录虽按 docs/文档规范.md 表格属"建议"保留项,但本文是台架
作业指导书,历史沿革查 git log 即可,正文只留当前有效动作。
2026-10-27 17:57:11 +08:00
wandering1 2b4c0e97c2 docs: ADC 注入流程 §4 补码值刻度图
§4 的「码」定义表只有文字与数字,台架现场容易把 TPAFE 的
152.59 µV 与 STM32 的 805.66 µV 混着用。新增一张刻度尺对照
图(docs/images/ADC码值刻度.svg),上下两把尺子分别标出
11430 码 ≈ 1.744 V 与 1000 码 ≈ 0.806 V,把"同一整数在两片
转换器上代表不同电压"变成可见的;正文补一句两把尺子差 5.3
倍、§9 每格必须写明所属通道。

生成器 tools/arch_diagram/gen_adc_code_scale_svg.py 沿用图形绘制
流程 §3.2 约定(纯标准库 / html.escape / newline="\n" /
ElementTree 自检 + 文字溢出预检);码制与 LSB 数据集中在
PANELS 常量,换芯片才重画。已登记到 tools/arch_diagram/README.md
与 docs/架构设计/图形绘制流程.md 的生成器表 + 变更记录。

目检用无头 Chrome 截图完成(cairosvg 未装,截图不入库)。
2026-10-27 17:25:51 +08:00
wandering1 e50d2b5cf0 docs(adc): §4 补「码」的定义与两片转换器的刻度对照
用户反馈"码这个单位第一次见"。补一张刻度对照表:
- TPAFE5160 16 位双极性,−32768~+32767,1 码 152.59 µV
- STM32 ADC1 12 位单极性,0~4095,1 码 805.66 µV

带换算示例(11430 码 ≈ 1.744 V,与 cal: 行 1743 mV 自洽),
并写明本文为何一律用码:固件打印的就是码,且把码换成伏正是本次
要验证的事,先换算等于默认了未验证的系数。
2026-10-27 17:19:13 +08:00
wandering1 c92d503851 docs(adc): 修 §5.2 表格渲染,讲清零点这步怎么填
原表单元格里写了未转义的竖线(绝对值符号),被 GFM 当成列分隔符,
整张表渲染成乱码,看不出要填什么。§6 判据汇总同病同修。

同时把这一步的操作讲清楚:
- §5.2 补"做什么"四步:断电短接 → 上电读 adc: → 抄进 §9.1 → 断电换下一路
- 明确本节只给判据,要填的表在 §9.1(原表看着像表单,实际是参考值)
- §9.1 记录表加"空载码值(浮空)"列与填法说明,让空载与短接两个数都留痕

表格列数已用脚本复检三份相关文档,全部对齐。
2026-10-27 17:17:03 +08:00
wandering1 dc9ae01f50 docs(adc): 更正步骤 0 判据——端子对 AGND 不是 1 kΩ
原判据写"端子侧应量到 1 kΩ 量级(串阻 + 转换器输入阻抗并联)",两处错:

1. 端子到 AGND 是串联通路:R31(1k) → AIN_7P → 芯片内部 1 MΩ →
   AIN_7GND → R32(1k) → AGND,合计约 1.002 MΩ。1 kΩ 只在串阻两端成立。
2. 芯片输入阻抗是 1 MΩ 恒定(TPAFE5160 手册 "Analog Input
   Impedance" 节),量级上与 1 kΩ 并联不出 1 kΩ。

改为三行分测表:串阻两端 ≈1 kΩ / TPAFE 侧对 AGND ≈1 MΩ /
STM32 侧对 AGND 高阻不定量。并写明本步只排除短路、不验收正确性。

顺带把手册的匹配要求写进去:AIN_nP 与 AIN_nGND 两侧外接源阻抗
要相等以抵消失调误差,R31 / R32 各 1 kΩ 即为此——这就是 R32 的
存在理由(匹配,不是分压),补强"本板无分压"的结论。

ADC通道映射说明.md §7「前端偏置」行同步补 1 MΩ 与匹配依据。
2026-10-27 17:12:54 +08:00
wandering1 9163a92d3b docs(adc): 前端拓扑改 SVG,③ 段定死 1:1(本板不是分压器)
ASCII 拓扑图把 C44 / R32 画成挂在 ADC7 下的一根竖线,读起来像 2:1 分压,
恰是文档要否掉的结论。改为两个节点分开画的 SVG,并加 STM32 侧对照面板。

- 新增 tools/arch_diagram/gen_adc_frontend_svg.py →
  docs/images/ADC前端电路.svg(纯标准库 + 文字溢出预检 + 幂等重跑)
- docs/测试说明/ADC前端注入验证流程.md §2、docs/硬件平台/
  ADC通道映射说明.md §7.1 的 ASCII 图换成该 SVG
- ③ 段(AINn ↔ 转换器引脚)定死变比 1:1:ADCn 节点只有
  {串阻.2, 滤波 C, 转换器引脚},无对地元件;"1k 到地"接在差分负端
- 305.18 / 1611.3 µV/码(读法 A)作废;数据可信.md §2.1 表改为
  引脚侧系数 152.59 / 805.66,卡 0 判据从"判别两种读法"降为
  "确认转换器 LSB 与逐通道映射"
- 顺带修 ADC通道映射说明.md §8 步骤 1 的 §5.1 自引用误判
  (文档名以 V0.0 开头被前缀规则误认,改写成全路径形式)

门禁:Keil 无关(纯文档 + 生成器);check_ids --strict、
check_doc_links --all --sections-strict、pre-commit 全过。
2026-10-27 17:08:56 +08:00
wandering1 343305b433 feat(adc): 心跳新增 adc: 行输出 9 路原始码值,并补卡 0 台架注入验证流程
背景:ADC 采集的软件链路已全部打通(节拍、语义取数、折算、相量、
200 ms 快照、104/UI 消费),但"读数对不对"从未验证过——卡 0 的
已知电压注入一直挂账。挂账的直接原因之一是读数出口不够用:
固件只有 cal: 行(UA/UN/IA 三路,mV)与 first: 行(9 路码值,仅
开机一次),验 8 个通道 × 3 个注入点要复位二十余次。

改动一(App/task/adc_task.c,v3.3)
- 心跳新增 adc: 行,每 10 s 输出 9 路原始码值,与 first: 行同序
  同格式,台架"改电压 → 读一行"即可对表,全程免复位。
- 不并入 cal: 行:9 个码值会把该行推到 168 字符,撞
  DBG_CON_LINE_MAX(192) 的静默截断边界(截断不报错,只会少打几路,
  是最难发现的台架假数据来源)。
- 无新增跨任务状态、无新增外设访问;栈 +36 B(局部码值数组),
  adcTask 静态最坏 1400 B / 余量 1160 B(底线 1024 B),stack_report
  PASS;静态 RAM 不变,Flash +188 B。

改动二(新增 docs/测试说明/ADC前端注入验证流程.md)
- 卡 0 的执行侧:注入点清单、期望码值表、零点/线性/映射/极性/节奏
  五步、现场记录表、安全红线、已知坑。
- 固化 2026-10-27 的网表结论:逐通道追 V0.1.tel 确认 ADCn 节点上
  只有"串阻 2 脚 + 滤波电容 + 转换器引脚",没有对地分流电阻;所谓
  "1k 到地"是 TPAFE 负输入脚 AIN_nGND 经 1k 拴到 AGND 的差分滤波。
  故本板不存在 2:1 分压,端子侧斜率 = 引脚侧斜率 = 6553.6 / 1241.2
  码/V。数据可信.md §2.1 的 305.18 / 1611.3 µV/码 确认不成立。
- 不验交流:台架无信号源,且五路单极性削顶。

改动三(索引与指针)
- docs/README.md 测试说明索引、测试文档模板规范.md 的 ADC 缩写行
  (原"待立")同步。
- 数据可信.md 卡 0 增加指向该流程的指针(本表只写判据,不写怎么
  接表笔)。

门禁:Keil 构建 0 错误 0 警告;check_ids --strict 通过;
check_doc_links --all --sections-strict 通过(193 文档 / 2871 处引用);
pre-commit 全过(含 cppcheck、编码规范、体积档、标定层与量纲回归
单测);两处内存台账已按 --write / --update 刷新。
2026-10-27 15:14:07 +08:00
wandering1 103e26e111 docs(编号): 变更记录行去掉自伤门禁的示例号——改为形态描述,净减 3 处
原行把已停发族的示例号原样写了三枚(段号形态两枚、网络条目号形态一枚)当探针证据。为说明
反模式而自己付余量,等于让下一个读文档的人替这次说明再交一次费;现改为「L 段号形态的新号」
与「F 条目号形态的新号」,机器面结论不变(那几枚探针号当年确实命中校验 3 错误级,git log 可查)。

注:本行来源未逐一核实(提交前工作区已有此改动);按内容判断与今日「讲反模式的文档自己别用
那个字面量」的口径一致,且实测去掉 3 枚字面量,才入库。
2026-10-27 14:42:12 +08:00
wandering1 403e2e558d docs(编号): 族总表最后一处描述与落地值对齐(接 4cf2df47 与 b5390bb4) 2026-10-27 14:19:40 +08:00
wandering1 4cf2df4770 refactor(注释): 同批收尾——烧录编排器、日志校验器与追溯校验里的 S4/S7 措辞换成平实语言
与 2fd8a864 同一件事,上一笔的 git add 只覆盖了文档与部分脚本,这三只漏在暂存区外:帮助文本与
两处注释里的内部阶段代号(自检台账判定、用例追溯校验)已换成读得到、查得着的说法,判据未变。

自查:三文件 noBOM / LF / U+FFFD=0;id-check --strict 与 doc-links --all 均 rc=0;工作树至此为空。
2026-10-27 14:17:35 +08:00
wandering1 b5390bb430 docs(编号): 停发结果回写族总表——允许继续发号收到 5 个族,并登记一处真空白
批次一与批次二落地后,族总表里三行标上停发结论(保护功能号转功能名、网络条目号转 §7 条目名、
台架阶段裸形已清零),允许继续发号从 8 个收到 **5 个**;registry 同步给这两个族加 retired 标记,
游标与 pattern 保留(保留登记只为让历史行不报未登记前缀,不代表可再发号)。

另登记一个真实空白面:某族 pattern 的数字上界只到 3,比实际用到的号段窄,已在 cursor_note 里写明
——这种空白不写出来,下一个人就会以为自己写的号在册。id-known-backlog 随之同步(台账仍只减不增)。

自查:id-check 带与不带 --strict 均 rc=0;本笔零代码。
2026-10-27 14:16:34 +08:00
wandering1 2fd8a86490 refactor(注释): 把内部阶段代号 S4 与 S7 换成平实语言——查不到的代号不算可检索锚点
用户 2026-10-14 就定过这条(以后没人知道这种编码,要简单明确),这次把最后两处内部分层代号清干净:
· 串口自检判据里的 S7 → 直接写自检台账联合判定;用例追溯里的 S4 → 写用例追溯校验。
· 涉及烧录编排器与日志校验器的帮助文本、两份数据目录 README 的字段说明,以及看门狗、存储维护、
  实机测试、链路延迟四篇文档的同一处措辞。

判据没变,改的只是**读起来能不能查得到**:S7/S4 这类号在任何登记表里都查不到定义,注释里留着,
后来人只能靠问人——而这类内部分层代号正是当年编号失控的起点。门禁:doc-links 与 id-check 均 rc=0。
2026-10-27 14:16:26 +08:00
wandering1 6fb9cd3a93 chore(编号/门禁): 补遗——改名器台账入库、一处 F-* 残留、覆盖率基线在完整树下重建
· id_aliases.json(+67/−7)与 scripts/rename_maps 两份映射表:批次二(保护功能号)与批次一
  F-* 半批用 rename_ids 跑时自动写的别名与映射,早该随批入库——别名表是改名的**必需产物**,
  留在工作区等于下一轮别人提交时被自家审计表当成新账(这类自循环历史上踩过四次)。
· test/host/net_socket 一行:F-* 收尾时漏 stage 的残留注释(B3 后向语义说明),属 0054ae62 的
  同批内容,此处补上,全仓该族活引用至此归零。
· 覆盖率基线**重建**:上一版是在 time_sync 套件编译不过的破树下打的,少算了该套件覆盖;现在
  用完整树重打,总闸 rc=0。
· simulator 两份 README 的页数 47→53 属 a275539c 漏项(我当时只 stage 了 docs 与 .dsh),补齐。
· 仓根残渣 undefined/(探针把变量当路径用生成的目录)与 tmp_dump_tc.py 移入 ci-artifacts/
  quarantine/,内容原样保留,仓根清干净。
2026-10-27 14:08:26 +08:00
wandering1 10ad8aa9b8 refactor(编号): 撤掉开机账本用例的族登记——定义位只留测试说明篇一处
道F 的判断成立且用机器验过:把 TC-HOST-BOOTSTAT 从 registry 撤掉后 check_ids --strict 仍 rc=0,
说明那 21 个号靠 开机账本单元测试说明.md 一处就够定义,族不提供任何额外判定,只多了一个
「改起来更便宜」的落点。代价是失去该族游标;接受,因为文档路线更严(加号必须写一行判据,
游标只拦号码大小)。族数 100 → 99,id-check 与 doc-links 均 rc=0。
2026-10-27 14:00:08 +08:00
wandering1 a64db43fe4 docs(任务规划): 通讯设置页销项与叶数口径同步(22 绑 / 11 未绑 / 待做 6)
按「完成即销」删 UI补齐 §2 顺序 1 整行并重编号、删依赖 bullet、开篇改为从记录 5 页开始;
§1 计数按生成器自身 parse_tree 实测(nodes=42 leaves=33 bound=22 unbound=11),分类表 7 改 6
并补闭合式(6 + 5 = 11);README 开篇剩余三项改两项、§1 表同步。

两条比数字更该留下的口径:
· §3 数据源表里通讯设置那行**保留并改写**,不整行删——「改后重启即生效」的真机判据与配置段
  数键数上限核对**确实未做**,完成即销销的是已完成,不是已落地一半。
· naive 计数从 22 纠正到 23(文件头示例行也算一次)。旧文档那个 22 恰好等于新的 bound 真值,
  不改就等于教人用错算法却碰巧对上,比错更糟。
2026-10-27 13:59:59 +08:00
wandering1 a275539c17 docs(全仓): 内容页黄金 47 → 53 的当前态同步——含钩子显示名,登记簿口径另笔
task-9 让内容页黄金从 47 涨到 53(通讯设置页六态),本笔只做**当前态陈述**的同步;真值全部本轮实测:
`simulator/tests/ref/*.bin` = **53**;`git diff 31ca4a1f..HEAD` 对该目录 = **
6 个新增、零修改** ⇒ 存量 47 张
逐字节未变(这条是关键:新增页不该让旧页重生成,否则回归基线就失去意义)。

**四类命中各走各路,这是本笔的全部难点**(分类比替换重要得多):
· 当前态 → 改,25 处页数,落在 16 只文件(AGENTS、钩子显示名、导航器 docstring、`lvgl-simulator` s
kill、
  门禁索引与 `ui-golden` 详解、UI 自动化流程、内容页架构、页面补齐规划与扩充方案、数据供给、自动化测
  试流程、覆盖率口径、测试开发标准流程、模拟器两份 README);
· 变更记录历史行 → **一条不动**,另在其下一行插入当日「47 → 53」新行 6 条(含判据与零漂移证据);
· **同数不同义 → 不动**:覆盖率口径里的「47 个 .c」「47 = 13+5+29」、ram_report 的表行号 47、`#47-D`
  诊断号、LSI 47kHz、47,360 栈字数、像素哈希 3476/3474 —— 一并替换就会毁掉六个不相干的事实;
· 带日期戳 / 自declare 冻结的快照 → 不臆改(数据供给篇那句上一笔已加「当时」,页面补齐规划里那张
  「2026-10-25 复核…剩 21 叶」的表自带「完成即冻结不回改」声明)。

复扫残留当前态 47 = **0**。⚠ 顺手纠一条**会教错方法**的陈旧:naive 计数 `grep -c '#page='` 上一笔写的是
22,现在真值是 **23**(文件头示例行也算一次)——旧文档里那个 22 **恰好等于新的正确 bound 数**,不改的话,
下一个人用错算法还能碰巧对上,比错更糟。

⚠ `AGENTS.md` 里本次有两件事同行相邻(本笔的内容页 53 页 + 批次三那句 `TC-*` 停发),**分两句说明**:
前者是计数同步,后者是昨天那条「批次三不坐」裁定的入口文案,二者不是同一件事。

钩子显示名改在 `.pre-commit-config.yaml`(47 → 53)。**这条必须与代码同批入库**:配置脏而未 stage 时
pre-commit 会直接报错挡住全仓任何提交(今天已实测两次),所以本笔先落它,把后面几笔的路清开。

自查:`check_doc_links --all` rc=0(203 篇)、`check_ids --strict` rc=0 且不可判定绝对
数 **979 未变**(新增
文本里的提交号与 `#page=comm` 没推高它)、`gen_task_table --check` 0、`check_bom_drift`
 0、18 只文件 noBOM /
LF / U+FFFD=0;行数变动 +49/−47 全部可归属(插 6、删 2、并 1),其余为 1:1 等行替换。登记簿销项与叶数
(`UI补齐.md` + `docs/任务规划/README.md`)**不在本笔** —— 那是口径变更不是计数同步。
2026-10-27 13:54:05 +08:00
wandering1 2e608118ce feat(对时): 8888 对时补一条操作记录留痕——与 104 对时对称,被拒不落痕
task-49 盘点盘出的唯一供给缺口,task-50 实现(道H 交付)。为什么这算缺陷而不是「维护工装不值得留痕」:
对时改变的是**其后每一条记录**的时标,而 104 侧的对时**已经留痕** —— 同一类行为两种结果,这个不对称
本身就是缺陷。FTP 上传不留痕则维持原状(那是传输动作,与「装置时钟被改了」不同类),本笔
刻意不扩面到它。

实现:`time_sync_handle_conn` 里 `sys_clock_set_unix` 的返回值原先是**裸丢弃**,现改为接住判
0,==0 才
投 `SYSLOG_OPER`(走 quiet 口,netTask 侧纪律,栈成本已在注释写明);**被拒零投**(不把失败记成改过时
钟);无合并锁存(连续两次对时留两条,不折叠);**epoch 语义零触碰、零时区补偿** —— 时基口径仍在用
户手里,本笔不替产品决定。

新用例四组十二断言:成功恰一条 / 被拒不落痕 / 连续两次两条 / 魔术字不符皆零。假件把 rc 做成可脚本,
并专门钉「文案出现次数」以证不合并;`sys_log.h` 用真实头(纯 stdint,走 task_watchdog 先例),零桩漂移面。

**停发口径的第一批**:新断言**不配 TC 号**,改用语义化用例名 + 函数名追溯,注释里标了口径出处 —— 裁定
能不能落地看的就是第一批,这条留在这里给后来者当样例。

证据:time_sync 92/92(存量 82 零回归);@build **0 错 0 警**,Code=235268 RO=26308 RW
=1572 ZI=136924
(与上一笔的差值是 728d6067 合账所致,不是本笔);栈**以表为证**:timeSyncTask 链 1272→1272 B 零增
量,own frame 152 不变,handle_conn 200 / post_quiet 40 / post 264 逐函数帧全等 ——
按今天刚定稿的栈判
据,「零增量」这句话必须是表,不能是论证。id-check --strict 0(零新号零裸形)、乱码/嵌套/BOM 净。

台账:`ram_baseline.py --update` 已记当日行(IRAM1 61.9% / CCM 87.9%)。覆盖率基线**留给 L
ead 重建** ——
上一版基线是在 time_sync 套件编译不过的破树下打的,少算了该套件的覆盖。

台账同步:本笔代码改了体积(Code=235268),RAM 预算台账受管区与文档快照区按 12:46 那次权威构建回填(ram_baselin
e --write 加 check_mem_numbers --write)。代码与数字不同笔,就是下一次 mem 钩子假红的来源——上一笔 d
ocs 提交被 mem-numbers 与 mem-budget 双双拦下,正是这个原因。
2026-10-27 13:49:38 +08:00
wandering1 13001f2ae4 feat(门禁): 栈判据定稿——静态 margin 唯一拦提交、运行时水位只告警、采集不健康整轮作废
task-32 裁定落成可执行件(道F 交付)。不是二选一而是**分权**:静态最坏链 margin 仍是唯一拦提交项(由
`stack_report.py` 守,它本就把运行时峰值取进 max);新增 `stack_gate.py` 管台架侧——趋势只出 WARN,
**绝对底线**(free_min < 25% cfg)是运行时唯一有 FAIL 权限的一档,**采集健康门不过 = VOID / exit 2**,
不红不绿、不进台账。把「daemon 死了 status 仍报正常、rx_lines=0」那类事故机械化:门不过与设备故障
exit 1 分开记,按码聚合的人不会把端口没开当成又崩了一次栈。

容差是推导的:tol = 上取整到 16 B 的 max(128 B, 2×实测摆动),实测 80 B ⇒ 统一 160 B,登记进
`scripts/stack_tolerance.tsv` 带来源列;**改数权限写死**——只有台架重测后才允许回填,禁止为让某轮变绿
而调大容差(被这把尺考核的人不得当场决定尺子的松紧),且这句话**紧贴数值写**。

`--selftest` 14 条能红,开发中抓到作者三个真错(身份戳正则把 __DATE__ 月份写成三位数字、一度把跨轮戳
不同当 VOID 会让判据永不可用、文档 §4.0.2 被 doc-links 抓跨文档串号)。**不接 pre-commit**:它的输入
是台架串口采集,提交时既无设备也无当轮日志,挂上去要么永远 SKIP、要么拿上一轮日志判这一轮的码(与
体积门禁那条假凭证同族)。
2026-10-27 11:31:53 +08:00
wandering1 728d60675f feat(UI/采集/104): 通讯设置页 + 开机账本 + adc_cal 可诊断化——三车道同树一次构建入库
三条道在同一棵树上交付,故合并成**一次权威构建**(@build 0 错 0 警,Code=235236 RO=26308 RW=1572
ZI=136924)后同笔入库;台账已按该构建回填(`ram_baseline.py --update` + `--write`、`chec
k_mem_numbers.py
 --write`),凭证与实际 .map 同源。归属如下:

· **通讯设置页**(道G task-9):新增 `Drivers/BSP/UI/ui_page_comm.{c,h}`(通道六注入,与死
区页同骨架同纪
  律),`#page=comm` 绑定使 bound **21 → 22**、内容页黄金 **47 → 53**(旧 47 页字节零变化,
新增六态含
  WAIT/OK 两张);`iec104_comm` 脏位 + store_save(**无事件位**)挂 defaultTask 同点位
轮询;`port_104` 由
  宏改走 getter、`IEC104_SERV_PORT` 删除;字体 +听/监(185 字全覆)。**实机链已闭环**:FTP 外改
[comm]
  的 ca/port → 复位 → 串口出现 `section 'comm' (2 keys)` 与 `i104: listening o
n 9004` → 还原 2404,全程无
  FAIL ⇒「重启即生效 + 端口真值」不是推断是实测。上限核对 6/8 段、2/16 键,超限现象由 TC-CONFIG-056/057
  钉死(注册 -1 + `comm init: FAIL` 锚 + getter 回 ROM),**不抬宏**。
· **开机账本**(道F task-12):新增 `App/util/boot_stats.{c,h}`——上电次数落 SD2506 用户
 SRAM(magic +
  小端计数 + 版本 + 异或校验),一次上电 = 1 读 + ≤1 写,**零 NAND、零卷锁、零配置段**;四态互斥
  UNKNOWN / FRESH / CONTINUED / RESTARTED(BLF=1 才算电池域掉过电),**读失败绝不回写**;
文案口径「自 RTC
  电池周期起」,**禁写终身次数**。复位原因优先级链从 `app_main.c` 的 if-else 收进一份真源(串口与屏幕同
  源);104 四个只增不清计数 + `iec104_serv_get_stats()` 留在 serv、未塞进 link(会被 open
/close 洗掉)。
  运行时长按用户裁定 = **只报本次开机以来**,零新增代码。新套件 `test/host/boot_stats` 21/21,五处注入
  **全部有牙**(含「漂一字节被校验和挡下而不是报 256 倍错账」)。
· **adc_cal 可诊断化**(道E task-43):三个 volatile 计数 + `adc_cal_get_stats()`
/ `adc_cal_note_persisted()`
  (水位**盖写非自增**,因为一次 save 覆盖整档,数 save 会留假未落盘);「差额 × 脏位」三态语义唯一落在
  `adc_cal.h`,其中「差额 > 0 且脏位恒 0」= 绕过语义 setter 的静默丢失;TC-ADCCAL-019~023。

三条**必须留档的自纠**(都是执行道自己报的,我不替他们润色):
① stdint 那条断链是**宿主套件抓到、通讯道先修**,采集道承认自己是重复添加者并删掉自己那份;
② 「exit 2 不是证据,断言变红才是」——采集道第一版反证注入了未声明标识符导致编译错,差点当成功;
③ 套件汇总行原写 `s_total/s_total`,失败时会打印「21/21 PASSED (failed=1)」这种自相矛盾的行,已改。

另修:`check_registration.py` 的 `SIM_EXEMPT` 加一行豁免 `App/util/boot_stats.c
`(依赖 I2C 与 RCC 位掩码,
MCU 专属;核过 `sys_clock.c`/`sha256.c` 同形态先例),注册反向校验 exit 1 → 0。发号 TC-IEC1
04-034、
TC-UIDATA-029 已实抬游标(`TC-IEC104-033→034`、`TC-UIDATA-026→029`)。

门禁:id-check --strict 与 plain 均 rc=0、doc-links --all rc=0、注册校验 0、cppche
ck / coding-standard /
bom-drift 0;iec104 179/179、ui_data 295/295、boot_stats 21/21、adc_cal 11
7/117、run_par 67/67;菜单 8 状态
池 5368 不变、内容页 53/53。**已知遗留**:内容页数 47 → 53 的全仓文本同步尚未做(另卡跟踪),本笔只保
证代码与黄金一致;面板注键真机那一腿缺 CLI,交台架道补。
2026-10-27 11:29:23 +08:00
wandering1 0ae9c10f24 docs(时间): 时基口径定稿——内部一律本地钟面(用户裁定「时基先本地为准」),并纠正本文自相矛盾
用户裁定原文:「**时基先本地为准**」。这条定的是**冲突时谁赢**:面板时钟页与 8888 对时把「本地钟面当
epoch」写入,而 104 的 `C_CS NA` 对时命令携的是 UTC,两条写入口**后写者赢** ⇒ 装置墙钟与主机本地时刻
恒差 8 小时。裁定结束「后写者赢」:**内部真源 = 本地钟面**,任何来源写入前都先换算成本地钟面再落库。

**顺手挖出这条 8 小时的真正根因:本文自己就是矛盾的**——§2 的术语表把 epoch 定义成「自 1970-01-01
00:00:00 **UTC** 起的秒数」,而 §15 网络校时协议字段写的是「**本地** Unix 时间戳,与电脑显示一致」;代码
按后者实现。所以「恒差 8 小时」不只是两条写入口打架,**规范文本也没统一过**。现在 §2 改成「本地时间戳:
把本地钟面按 UTC 记法数出来的秒数,内部不加任何时区偏移」,§13 那行旧建议「如需 UTC/时区可在 API 层
加偏移参数」一并标作废(它会把「装置不存时区」这个优点拆掉)。

**为什么选本地**:日志时标、UI 显示、FAT 文件时间三者都是**给现场电气工程师读的**,跟装置所在地钟面
一致才没有解释成本;装置不存时区、不做夏令时,也就没有「时区参数配错」这一类故障。

⚠ **本笔刻意不做的一件事,也是本笔唯一需要人看的地方**:104 **上行**时标 `CP56Time2a` 按标准应发 UTC,
而 `iec104_epoch_ms_to_cp56()` 现在是把内部值**直接按 UTC 分解**发出——即发出去的是本地钟面值。两条出路
要么给装置一个时区常量并上行前减偏移(标准符合,但与「不存时区」相冲),要么维持发本地值(同时区现场
看着正确,第三方主站按 UTC 解读会差 8 小时)。**这不是 bug 修复,是产品对外语义决定,牵动送检与第三方
主站验收**,所以本轮**一行代码都不改**,只把分岔与后果写进 §1.1 末,等单独裁定。

自查:`check_doc_links --all` exit 0(198 篇)、本篇 `--sections-strict` 通过、noBOM
 / LF / U+FFFD=0 / 结尾
换行齐、不可判定绝对数 979 未变;本笔**纯文档**,零代码零编号。此刻另有五条道在飞(通讯页 / 计数器 /
对时留痕 / 台架判据文档 / 记录页设计),故只提交这一只文件,其余按道分笔。
2026-10-27 10:50:16 +08:00
wandering1 a10d24c09c docs(任务规划): 运行时长口径落定——用户裁定只报本次开机以来,清单项去掉「待裁定」
用户裁定原文:「**A 只报本次开机以来**」。本笔把这条裁定写进 `UI补齐.md` 三处(§2 第 3 项判据、状态列、
§3 数据源对照行),并把它**能省掉什么**与**不能顺手砍掉什么**分开写清——这是本笔唯一需要动脑的地方:

· **省掉的**:跨开机累计要自造正源(往 RTC 芯片用户 SRAM 存累计秒数、处理电池失效判读、文案还得写「自
  RTC 电池周期起」)。选了 A,这一整套都不做;UI 那一栏改为**明写「本次开机以来」**,免得读者误以为是
  累计值——清单里那句「新计数器要明确掉电保持还是本次运行、不得含糊」是靠**把口径印在屏幕上**兑现的,
  不是靠注释或文档。
· **不能顺手砍掉的**:上电次数是**另一个数**(次数 ≠ 时长),它的正源问题一点没变——仍无现成计数器、仍
  建议 RTC 用户 SRAM、文案仍**禁写「终身次数」**、仍要处理电池没装或失效时读回全 1 / 全 0 的判读。派给
  执行道的卡片里同样写明「本裁定不覆盖上电次数,要捆在一起砍先问 Lead」,免得一次裁定被下游合并解释。
· **不受影响的**:复位原因(RCC 标志读后即清 ⇒ 必须开机快照驻留)与 104 统计(现有量全是控制量 ⇒ 需新增
  只读计数与 getter,就近留 `iec104_serv.c`、不并进通用统计模块)。

流程说明:这只文件此刻还带着通讯道在飞的另一处改动,本笔只提我这一处(登记簿归 Lead)。不等通讯道交回
的理由是——**这条未决口径正被另一条道当作开工前提在读**(task-12 已派出去,那半边判据要照这一行写),
把它留在工作区里等合并,等于让裁定晚于使用。

自查:全文再无「待用户裁定」残留;noBOM / LF / U+FFFD=0 / 结尾换行齐;`check_doc_links --all` e
xit 0(198
篇)、本篇 `--sections-strict` 通过;本笔零代码、零编号增删,`id-check` 与不可判定绝对数不受影响。
2026-10-27 10:25:50 +08:00
wandering1 4c4c1d2168 docs(编号): 批次三裁定「不做」入档——TC 族保留现状但即日停发
用户裁定原文:「**批次三,不坐**」(即不做)。本笔把裁定连同**理由与后续硬口径**一起写进 `docs/编号规范.md`,
而不是只把那一行划掉——因为「不做」最容易被误读成「那就可以继续发 TC 号」,必须把它关死。

**为什么留着 TC 族与今天的定调不矛盾**:§4.1 那条判据是「有脚本按字面量匹配它」,而 `TC-*` 是**唯一真正
满足这条判据的族**——追溯门禁与 40 套主机单测按字面量读它,C 断言标签、测试函数名、文档用例表三处同
一号,是「代码 ↔ 文档」双向核对的机器把手。清它的代价不是改文本,而是**换掉追溯机制**(候选方案「用
例名即标识」要把追溯门禁重写并重打基线),期间测试与文档的对应关系会处于**断裂态**,而测试本身就是提
交门禁(跑全部 40 套并守覆盖率基线回退)——拿它做不可逆试验不值。**结论写进文档**:机器面自解释的族
可以保留;字母号的痛在「人读」侧,解法是**别再造给人读的号**,而不是把机器面的把手也拆掉。

「不做」之后跟着两条硬口径(这才是本笔的实际效力):
① **本族即日停发**:游标冻结、现存号只减不增,**新用例一律用语义化测试函数名 + 文档表格行名,不再配
   `TC-` 号**——已作为一行加进 §4.1 的『已停发』栏,并在『允许继续发号』栏开头写明「该族虽仍被脚本读,
   但发号已停,其余 7 族不受影响」,免得两栏看起来互相打脸;
② 将来真要清,走 `scripts/rename_ids.py` + §7.3 五步**单独开卡**,前提是先让追溯器**同时认新旧两种形态**、
   并行核对通过再谈切换;**不许先改文档再改代码**(凭空造出悬空号,校验 3 会当场拦)。

三处口径同步:§9.1 批次三正文(裁定 + 理由 + 两条口径)、§9 存量表该行的处置列(「需要先裁定」→「保留、
即日停发」)、§9 顶部执行结果表的批次三行。复核:全文再无「等你裁定 / 需要你裁定」这类悬空表述(唯一
命中的是 `UI补齐.md` 里**运行时长口径**那条,是另一件仍未决的事,没动)。

自查:`check_doc_links --all` exit 0(198 篇)、本篇 `--sections-strict` 通过(新加的「§
8 校验 3」是紧邻本文
自引用,符合紧邻写法)、noBOM / LF / U+FFFD=0 / 结尾换行齐;本笔零代码、零编号增删,`id-check --strict` 与
不可判定绝对数不受影响。
2026-10-27 09:56:05 +08:00
wandering1 c0d7bb9c8e docs(门禁): mem-budget 第 6 节补一条盲区——同码凭证按 git 索引生成,多人同树时必红
今天道G 报出 `check_size_gate.py --local` 单跑 exit 1(代码指纹与体积测量指纹不一致),我复核后确认这不是
预算问题、也不是谁改坏了台账,而是**该凭证的定义在多人同树下必然不成立**:代码指纹取的是 **git 索引里的
blob**,而此刻工作区里有别的任务在飞、尚未入索引的改动 ⇒ 两边算出来的东西本来就不是同一份内容。

写进 §6 的三点判据:
· 它**只挂在 `scripts/ci_local.py` 的 L0c,不在这 51 条 pre-commit 钩子内** ⇒ 红它不等于提交
会被拦,别在
  提交被拦的清单里找它;
· 报错若同时列出「未入索引的文件」而那些文件正被别的任务改 ⇒ 等它们入库后统一 `@build` →
  `ram_baseline.py --update` 补凭证;**绝不为把它调绿去 `git add` 别人在飞的改动**(这条比前两条更要紧,
  今天就这样发生过一次:别人已 staged 的文件会被我的 add 顺手卷进我这一笔);
· 本节写作时凭证**仍是红的**(回填发生在通讯卡入库之后)——我只写成因与判据,**不预告还没发生的结果**,
  这正是 `pre-commit使用说明.md` §2.5 那条「注释陈述事实不陈述意图」在同一天的第二次应用。

自查:`check_doc_links --all` exit 0(198 篇)、本篇 `--sections-strict` 通过、noBOM
 / LF / U+FFFD=0 / 结尾
换行齐;`id-check` 未受影响(本笔零编号)。本笔零代码,且此刻两条道正在写 `Drivers/BSP/UI/` 与
`App/algo/`,故只提这一只文档文件。
2026-10-27 09:47:23 +08:00
wandering1 f5d524fdde feat(门禁): 把「钩子跑在谁身上」机械化——ci_local 新增 L0a 解释器预检 + 环境动手术的顺序与回滚
task-33 诊断结论的落地(道G 执行,环境**一个字节没动**:不装包、不重建、不改 requirements 约束)。

**要防的是什么**:`.git/hooks/pre-commit` 把 `INSTALL_PYTHON` 钉在 `.venv`,而 43 条
`language: system` 用
裸 `python` ⇒ pre-commit 本体走 `.venv`(3.12.4)、钩子 entry 走 PATH 首位(3.14.7,零第
三方包)。今天
不炸是**巧合**(那 43 条模块级 import 全是标准库,唯一要 fontTools 的那条自己解析解释器)。真正的危
险形态是:某条钩子在**跑到它那一刻**才报 `No module named ...`——一次提交里前 14 条已经改写完工作区、
第 15 条才崩,现场最难看,也最容易被误当成代码问题。L0a 把这件事提前到门禁第一段。

**FAIL 判据刻意收窄成三事齐备**:模块级第三方 import + 该脚本不自解析解释器 + PATH 首位那个解释器
真缺包。惰性/条件导入(`make_font` 的 fontTools 在函数体内)只列为**候选**、不判决——否则就是假阳性
(见下)。退出码 2 = 环境错误,已写进文件头退出码段与用法。

**道G 自己推翻过自己两处,都留在文档里没删**:
① 上一版诊断说「42 条里唯一需要第三方包的那条自带解析」是**宽松正则**审出来的(把注释与字符串里的包
   名也算命中),机械口径下按模块级 import 判是 **0 条**,条目数也因 nested-comment 落地从 42 变 43;
② 第一版 L0a 把 font-charset 判成 FAIL,他拿真解释器实跑反证(`C:\Python314\python.exe
   scripts/check_font_charset.py` = exit 0,因为 fontTools 的导入在函数体内、加载期不执行)
⇒ 判据改窄。
**红-绿自证**:临时假仓库三条钩子(要 fontTools 且不自解析 / 同样要但自解析 / 纯标准库)→ 坏的那条判
FAIL、好的判 OK、整体 rc=2;真实仓 → 43 条、forced 缺包 0、候选 fontTools、exit 0;同一预检在 .venv 与
PATH 首位两个解释器下都 exit 0。

文档 §5 重排成**依赖表(§5.2) → 动之前死顺序(§5.3) → 遗留账(§5.4)**(原文按追加顺序把失效顺序插成了
§5.4,读起来先结论后依据;重排时同步修掉块内那条会指错的「见下面 §5.3 第三条」,以及 ci_local 里指向
死顺序却写着 §5.2 的指针——这两处 doc-links 都**静默放过**,因为本文恰好有同号小节,见 §3.5 盲区)。
四种现场(删/换 `.venv`、只换包、换 PATH 首位、改 requirements 约束)逐行钉死「第一现场 / 症状 / 还能
动什么」,回滚按现场分条不混用:freeze 备份放仓外、只 `--force-reinstall --no-deps` 单包不 `-U`、
`pre-commit clean` 会重建别人的钩子环境所以必须先要窗口、最后手段才删 `.venv`(删前记住基底是 Anaconda,
换机复制不出来)。

⚠ 一条与本笔无关的既有红灯(道G 报出,我核过成因):`check_size_gate.py --local` 现在 exit 1 —— 它按
**git 索引 blob** 生成代码指纹,而工作区正有 comm 道在飞的 `App/protocol/iec104/iec104_comm
.{c,h}` 未入
索引,「同码」必然不成立;**该脚本不是 pre-commit 钩子**(只挂在 ci_local),所以不拦提交,但别人跑
ci_local 会看到它,别误判成 L0a 新加的东西。台账回填等这批在飞代码提交后统一做一次。

自查:py_compile 0、`--preflight-only` exit 0(两个解释器下都是)、`check_doc_links --a
ll` exit 0(198 篇)、
本篇 `--sections-strict` 通过、`id-check --strict` exit 0 且不可判定绝对数 **978 未变**
(写文档没吃余量)、
mojibake / bom(81) / nested-comment(409) 全 0、尾随空白 0。
2026-10-27 09:42:20 +08:00
wandering1 251268992e docs(skills): 收录陈旧计数同步流程 + 补台账回填动作 + 去掉技能文里自伤门禁的裸形
三只 skill 文件收口(队友写成,Lead 核后入库):

· 新增 `stale-doc-count-sweep`:把今天做的「一个事实数变了之后全仓同步」钉成流程——从权威来源**实测**真值
  → 全形态扫描并**逐条分类**(当前态改 / 变更记录历史行只加当日新行 / 同数不同义的误报不动 / 带日期戳的
  测量只加「当时」锁口径)→ 逐条字面替换且每处断言命中数 → 被改文件全文通读核各小节 → 复扫残留归零 →
  跑门禁分笔提交。这份流程的价值全在**分类**那步:今天有 5 处「27 → 40」是历史事实、1 处「< 40KB」是同数
  不同义(绘制缓冲红线),一并替换就会毁掉它们。
· `mem-budget`:补上 `ram_baseline.py --update`(只往 tsv 追加趋势行)与 `--write`(才同
步台账受管区)的区别、
  以及「提交前台账怎么回填」的动作——这个坑是 Lead 本人 05:0x 踩的(用错一枚参数造出一次真的 mem-budget
  FAIL),写下来比口头转告可靠。
· `task-worktree`:把文中 4 处**自伤**的裸形改成形态描述——该节讲的正是「单字母紧跟数字」这类形态怎么被
  校验 2 计数,结果例子自己就是那种形态,等于技能文自己吃门禁余量。改完不可判定绝对数 **982 → 978**
  (余量 +4),叙述信息量不减:形态与属主都还写清。

⚠ 这条教训值得单记:**文档在讲某个反模式时,自己不要用那个反模式的字面量**——否则每次读它的人都得替它
付余量。同批 `docs/编号规范.md` §4.4 也已登记这类误判面。

自查:`check_ids --strict` exit 0、不可判定绝对数 978 / 上限 1,166;三文件 noBOM / LF / U
+FFFD=0 / 结尾换行齐。
2026-10-27 09:11:18 +08:00
wandering1 c457da0210 docs(编号): 批次二结果写回规范——存量清点改执行态、护栏不下调、位号误判面登记
§9 顶部加执行结果表(原清点表保留并**标明是动手前基线**,不然下一个人会拿它当现状):
· 批次一(登记簿旧号 / 阶段号 / 台架阶段裸形 / 网络条目号):活文档清零,顺带清 3 处裸形,位号目录整目录排除;
· 批次二(保护功能号 28 个):代码与测试 215 处 + 文档 194 处 + 配置注释 3 处 + 入口文档 2 处;活文档里该
  族只剩**冻结的变更记录行 40 处**与**一处原始串口日志**(真机抓包证据,改它等于篡改现场 ⇒ 永久保留);
· 批次三(测试用例族 561 站点):**未动**,等用户裁定——清它等于换追溯机制,要重写追溯门禁并重打基线。

账面(门禁自身接口实测,非估算):编号字面量 **8,787 → 7,828**,不可判定绝对数 **1,161 → 978**(上限 1,166,
余量从 5 格宽到 188 格)。§8.1 与 §9 里三处 8,783 同步为终值 7,828(8,783 是批次二中途的读数,留着会让人
以为那是最终态)。

两条口径裁定写进文档,免得下次重辩:
① **不下调 `decidable_ratio_baseline`**:这批删的都是可判定引用,分子分母同缩 ⇒ 比值 86.79% → 87
.46% 是
   **纯稀释**(绝对数反而还掉 183 处)。护栏是**地板不是 KPI**,跟着稀释往下挪等于每次清号都把闸门压下一格。
② **位号与记号误判面**补进 §4.4:位号目录整目录排除(那类 `T1` 是变压器位号)、`N-1` 是傅氏公式求和上界
   (清了会破坏公式)、以及今天新踩到的——**裸正则会把它自己的版本号当成功能号**(某第三方库版本号里
   含形似功能号的片段,实测误报 10 处 / 2 只文件)。清号必须带**左边界**并跳过反引号代码段。

自查:`id-check --strict` exit 0(校验 1~6 无错误)、`doc-links --all` exit 0(198 篇
)、本篇 `--sections-strict`
通过、字节卫生干净;本笔零代码。
2026-10-27 09:11:11 +08:00
wandering1 0054ae629a refactor(编号): F-* 网络设计条目号转语义说明——批次一收尾,代码注释 43 处 + 文档 9 处
批次一(不碰门禁即可清)的最后半批,原派道中途失败且**未留任何改动**(Lead 核实那批文件零 diff 后重派
setpage 执行,14 只文件 / 46 处),测试侧与一张生成器共 9 处由 Lead 收尾。

做法:**逐处先读属主文档 §7 速查表里那条的语义**,再改写成「一句话结论 + §指针」,同号跨文件同一措辞,
无一处机械删号(例:`F-NET-7` → 「唯一读者红线(docs/网络/网络自愈架构设计.md §7 I7)」)。属主登记处
**12 条定义行原样保留**、不删登记族(删了历史行会报未登记前缀),只在该章加停发句。

顺带清掉 **3 处裸形**(`T6` → 「台架实测」、`M4-lite`、`Q1` 语义化)——裸形正是 id-check 校验 2 抓的形态,
属净减。测试侧收尾时两条纪律:主机侧**断言字符串必须保持 ASCII**(`ns_s3_msg.c` 等三处的号在 CHECK 文本
里,改成 `sole reader of the global register` 而不是中文);板端注释可用中文。

生成器 gen_net_instability_svg.py 文案改动 → 同批重跑产物 `docs/images/网络不稳根因总览.svg`:只有那一
行的**框宽随文字自适应**(526 → 551,右缘 1411 未越界),画布 1560x1468 不变,无溢出告警。

⚠ 本笔**只含代码注释面**:该半批的文档面(BSD 函数调用关系 9 处、属主文档 §7 停发句、
生成器与产物那张网络不稳图)已被上一笔 `git add docs tools` 一并收走,两笔合起来才是完整的 F-* 批次。
自证:@build **0 错 0 警**且 Program Size 与改前**逐字节同数**(Code=233900 RO=26104 RW=1
536 ZI=136808,
注释无误伤的机器证据);net_socket 457/457、iec104_serv / net_pending 两套 exit 0;cppchec
k 钩子参数零
发现、coding-standard 0(lftpd_inet.c 那 4 条是存量且该目录本在钩子 exclude 内,用 HEAD 副本对照
甄别过)。
2026-10-27 09:05:27 +08:00
wandering1 4c74cfa825 refactor(编号·批次二): 文档侧 194 处保护功能号改成功能名,定义表 7 张首格改语义标识
批次二文档半(道 gate-docs 执行)。先纠三个数的口径账,别再拿任何旧数当准:**234 处是准数** —— 卡片写
52(Lead 用了门禁 Checker 的引用集合,它**刻意排除属主文档内部的定义位**)、道里先报 265(裸正则把
`SDL2-2.32.10` 里的 `L2-2` 当成功能号,误报 10 处)。最终边界口径 = 带左边界 + 跳过反引号代码段。

· 19 只文件 HEAD 共 234 处 → 现 40 处,**40 处 100% 落在变更记录行**(冻结历史,按 Q3 一条没动),
  非变更记录残留 **0**;改写 163 行 / 16 只文档。站点最多:规划文档 110→37、相量层单测说明 25→1、
  采集与数据处理短板评测 21→0、App/algo/README 26→0。
  (`App/algo/README.md` 由上一笔代码提交带上车,路径归属已在该笔正文注明,内容是本批改写)
· **定义表首列由编号改成语义标识**(编号规范 §3.3「表首格就是短语」的完全形态):首列原为编号的表
  共 **7 张**(不是 5 张),删掉与之重复的「语义名」列;表头标签按域词区分——三张 L3 保护**元件**表
  保留 `| 元件 |`,四张 L1/L2 表用 `| 功能名 |`(把「元件」统一洗成功能名会丢掉领域信息)。
  七张表逐张核:表头竖线数 == 分隔行 == 首条数据行 == 列数+1;与 HEAD 逐块对拍**净新增不一致块 0**,
  并且正是这个对拍抓到第一版「三张表数据行已删列、表头没删」的破表。
· 7 处删号留下的残词/重复解释括号人工收口(如「L1-5(通道标定)」→「通道标定(一次系数 + 零漂)」),
  复扫待收口站点 0;措辞逐字取自映射表,无第二种说法。
· tools/arch_diagram 三只生成器 4 处(3 处 docstring + 1 处图形文案)与产物同批:重跑后**只有位图那张
  变 2 个 text 节点的换行位置**,画布 1580x740 与总行数不变,另两张逐字节未变;改前先干跑对照证明三张
  svg 原本与生成器一致(不在 stale 基线里)——`check_generated_fresh --only docs-svg` PASS。

本笔另含 **F-* 半批的文档面**(同一轮 `git add docs tools/arch_diagram AGENTS.md` 一并收进
,非误伤):BSD
函数调用关系里 9 处反引号紧邻指针、属主文档 §7 的停发句与导读行(**12 条定义行原样保留、不删登记族**)、
以及 `gen_net_instability_svg.py` 与它的产物 `网络不稳根因总览.svg`(「唯一读者红线」那条的框宽自适应
526 → 551,右缘 1411 未越界,画布 1560x1468 不变)——该半批的**代码注释面**在下一笔。

⚠ 因 `docs/任务规划/登记簿.md` 与 `docs/任务规划/UI补齐.md` 正被另一张卡(UI 叶数复核)改动,本笔**不含
那两只文件**,批次二的 §9 存量收尾与它们同批提交。
2026-10-27 09:05:24 +08:00
wandering1 b7c0889cc7 refactor(编号·批次二): 代码与测试侧 215 处保护功能号改成功能名,零行为改动
用户裁定「不要用字母加数字的编号,语义标识是最好的」后的批次二代码半(道 ui-param 执行,逐文件站点数与
自证见其交付)。唯一口径 = 映射表 ci-artifacts/lprot_map.tsv 的功能名列原文,**零自造同义词**;L2.5 与
L-TEST 经实测各 0 处(不是本族),TC 族一字未动。

固件 22 文件 128 处(adc_task.c 21、phasor.c 22、phasor.h 13…),主机测试 13 文件 87 处(pha
sor_test.c
57…);设计文档指针新增 19 行,另 16 只文件本来就写着规划文档 ⇒ 不重复加。

**两条只有真改过 215 处才会踩到的坑,都写进注释规范实践**:
· 指针**不能接在原句尾部**——那会替原文一个未闭合的半括号封口,实测咬坏 App/algo/sample_ring.h 这类
  跨行句 ⇒ 指针一律**单独成行**;
· 号删掉会留下**叠词**(「自检失败闭锁 闭锁判定」「定值校验和 定值巡检」)⇒ 复扫并收口 4 处,措辞只用
  映射名本身;具体对象需要留住时写成「自检失败闭锁(采样故障闭锁)」。

自证(不靠嘴说):改前把 35 只文件原文备份到仓外 temp,逐文件比 `/*`、`*/` 计数、三类括号计数、行数增量
恰等于指针行数、全角括号增删相等、残留号 0 ⇒ **35/35 通过**;Lead 复核后跑权威 @build **0 错 0 警**,
Program Size `Code=233900 RO=26104 RW=1536 ZI=136808` —— **与三条道各自改前改后测的四数逐
字节同数**,
这就是「只动注释与文本」的机器证据;八套主机单测 exit 0,cppcheck 按钩子参数零发现,coding-standard 0。

文件头「修改记录」里的号**一并换名、不还原**(Lead 裁定):这些号是全仓退役的,留一个查无此号的引用比
留一条改过名的条目更坏——「冻结历史不回改」保护的是**别替历史改口**,不是保护一个再也查不到的字符串;
id-check 对变更记录行本就豁免,两种选择都不影响门禁。
2026-10-27 08:59:26 +08:00
wandering1 26a97e99f9 chore(门禁): 配置注释里的三个功能号改成功能名(批次二范围内、由 Lead 改的 config)
批次二(保护功能号转语义名)的范围按写域切给两条道,但 `.pre-commit-config.yaml` 里也挂着三处号,而
配置是 Lead 写域——注释归注释,不占任何钩子行为,改动不影响 YAML 解析的 51 条口径。

· `7h) ADC 采样有效性校验(L1-6)` → 去掉号,条目名本身已完整;
· `7i) 保护定值模型(P1 / L5-1 载体)` → 「定值校验和载体」(P1 同时是 gitlint 规则名的撞形,一并去掉);
· `规划 §3.3 L3-5` → 「规划 §3.3 过频 / 低频」(按 ci-artifacts/lprot_map.tsv 的唯一口径,未自造词)。

validate-config 退出 0;改后本文件内 `L<层>-<号>` 正则命中 0。其余 219 处代码/测试与文档侧由两条道并
行处理中,措辞同表;`tools/arch_diagram/` 生成器 5 处已转给文档道与三张 svg 同笔(动 docstring 不重跑
生成器会破 generated-fresh——这正是该钩子存在的意义)。
2026-10-27 08:02:22 +08:00
wandering1 c121eb9773 docs(任务规划): 复核菜单树叶数(42 节点 / 33 叶 / 已绑 21 / 未绑 12)并写清判定方法
按 ui_menu_tree.txt 用生成器自己的解析器(tools/menu_gen/gen_menu.py 的
parse_tree)重算:节点行 42、叶 33、已绑 #page 21、未绑 12;与生成物
UI_MENU_TAB_COUNT=42、UI_PAGE_MAP_COUNT=21 逐项对上。两份规划文档现有的
33/42/21/12 表述全部成立,故只补判定方法与复核命令,不改数字。

原 §1 写「重算方法见本节末」是悬空引用——§1 末尾并没有这一段。本次补
「叶数判定与复核」子节:节点行定义(非空、非注释行)、叶的缩进判据
(等价 ui_menu_tab_has_children==false)、#page 绑定判据、可重跑的复核
命令与预期输出,并记下三个错算法:把 42 个节点行当叶(多算 9 个菜单)、
grep -c 取 #page= 得 22(文件头注释里的示例字样也被算入)、按叶子名去重
得 29(参数/定值/控制字/软压板 在「整定」「查看」下各一份)。

README §1 同批加方法指针。只改这两份文档,未动代码与生成物,未推送。
2026-10-27 07:45:11 +08:00
wandering1 13f784430d docs(UI): 内容页黄金参考 40 → 47 页补齐剩余当前态(模拟器 README 与 lvgl-simulator skill)
上一笔 31ca4a1f 的「全仓同步」漏了几处当前态计数,按实测真值补齐:
simulator/tests/ref/shot_*.bin 实测 47 张、check_content_pages.py 的 PAGES 47 项。

· simulator/README.md 文件职责表「内容页 40 页」→ 47 页
· simulator/README.md 脚本表「③ 40 页无头截图」→ 47 页
· simulator/tests/README.md 文件表「40 页 × 3200 B」→ 47 页
· .dsh/skills/lvgl-simulator/SKILL.md 五步门禁「11 页黄金参考」→ 47 页
  (同一计数的更早残留,一并改成真值)

不改:各文档变更记录里的「27 → 40」历史行,以及 UI_自动化测试流程里
「覆盖当时 40 页中的 37 页」的 2026-10-26 测量口径——当时就是那个数。
零源码改动,golden 参考本体未动。
2026-10-27 07:43:46 +08:00
wandering1 95beaab313 refactor(编号): 第一批清号——登记簿旧号/阶段号/台架阶段裸形三族清零,位号目录排除
按 §9 批次一执行。**这批的关键发现是「看着像 62 处编号,实际能算编号的只有一小半」**,所以先分类再动手,
没有按站点数硬清:

· **真·编号(已改名)**:`N-6`(`MDK-ARM/tcp_reconnect_probe.py` 的「TRAP-NET-17 / N-6
」→ 只留 TRAP 锚点
  + 中文说明);台架阶段裸形 `T0`~`T3` 全部转成场景名——`e11_keepalive_probe.py` 的「静默对端 / 正常空闲存活」、
  `ftp_auth_bench.py` 的「匿名登录 / 未登录直接 NLST / 错口令锁定」、`serial_tool.py` 自检里的「行拆分 /
  解码回退链 / 时间戳行格式 / 端口建议」、`net_test_task.c` 与 `CH395F_Test_Guide.md` 的「空闲存活场景」、
  网络自愈设计里的「三路审计」。另把 `test/host/iec104_master.py` 的变量 `T0` 改成 `t_start`(那是起始时刻
  变量,被裸形族误抓)。
· **不是编号、但被误判(按 §4.4 处理,不改语料)**:`tools/netlist_semantics/` 里的 `T1` 是**网络变压
器位号**
  (硬件知识库),整目录进 `excluded_paths`,与 `docs/硬件平台/` 同口径;`BSD_Socket_API_函数调用关系.
md` 的
  `T1/T2/T3` 是 **Mermaid 节点名**,已改成语义节点(`RetryTick`/`PendTick`/`PendShimTic
k`/`ReconcileTick`)——
  图本身没变,只是节点不再叫字母号;`docs/门禁说明/gitlint.md` 里的 `T2` 是 **gitlint 自己的规则名**(不是本仓
  的号),已改写成规则描述;`docs/算法/傅氏算法详解.md` 的 `N-1` 是**数学记号**(求和上界 `x(N-1)`),保留不动,
  并在 §4.4 登记为「唯一已知误判」。
· **规范自身两处示例**顺手去掉字面量:`S3 / TM-PHY-01 / DP-03` → `S3 / TM-… / DP-…`;「报告 N-
16」→「报告 +
  登记簿旧号」。

结果(用门禁接口复测):`TM` 族 0 引用、`T-TEST` 族只剩规范自身 2 处示例、`N` 族只剩数学记号 1 处;
`F-*`(38 站点 / 12 个号,代码注释里的网络设计条目号)**留下批单独做**,因为每处要读懂语义、不能替换字面量。

口径变更已写进 §4.4:位号目录 `tools/netlist_semantics/` 进排除面;`N-1` 声明为已知误判。歧义面收窄后,
新错误级仍为 0、`id-check --strict` exit 0。

⚠ 这批**刻意没有复活「别名表洗白」那条路**:`N-6` 这类死号不进 `id_aliases.json`,让门禁继续咬将来的残留
引用(与 FTP 死号同一处理,见 §5.7)。
2026-10-27 07:39:00 +08:00