Files
STM32F4-Base/.dsh/skills/stale-doc-count-sweep/reference/steps.md
T
wandering1 7b05d7bfd4 docs: 任务规划目录收缩——只留推进顺序与硬件缺陷,其余待办归模块文档
按用户裁定(2026-11-10)把 docs/任务规划/ 从"全量待办表"收成两个文件:

1. 登记簿.md 只记 V0.1 硬件缺陷 → V0.2 改版要求(双转换器无共同采样触发、
   IA 前端差分滤波限制谐波带宽)。原 §1/§2/§4/§5/§6/§7/§8/§9 的待办按
   "待办跟着所属模块走"清空,四类事实在删除前先落到新归属:
   - 两点标定开工前要先拍板的三件事 → 算法层设计说明 §13.13(新节)
   - 通讯设置页真机判据 → 网络配置说明 §3.6 内联
   - 缩堆迁 CCM 后半、开入开出重开条件 → 原本各模块文档即唯一权威
2. 暂缓-RS485.md 删除,其唯一不可丢的"采集链路测试可验证性约束"三条与
   完成判据并入 产品需求设计文档 §5.10。
3. 任务规划/README.md 去掉全部历史叙述(UI 补齐销项流水、net 收口过程、
   故障录波近千字台账),只留:怎么用、条目规则、生成物单写者纪律、
   推进顺序表(每行只写当前状态与卡点)、维护约定。

同步改写全库引用(约 60 处):AGENTS.md、docs/README.md、产品需求、UI、
子系统设计、内存管理、环境与部署、算法、测试说明、门禁说明、问题记录,
以及 App/ 与 Drivers/BSP/ 的头注释、脚本与 .pre-commit-config.yaml 注释。
顺带修掉三处已失效的引用目标:链路延迟测试的队列往返重验项改指实机测试
实施指南 §7.3;并行工作树的 <ID> 行去掉已退役的 N-x/S-x/T-x 编号族;
任务规划 README 的 §1 旧编号在技能示例里的引用。

门禁:check_doc_links --all --sections-strict 214 篇通过、无法判定 0;
pre-commit 全 Passed(doc-links / mermaid / 任务表 / 内存数字 / BOM /
UI 像素回归 / generated-fresh / layer-deps / bsp-err / skill-size);
keil-build 0 错误 0 警告(Code=255160 RO=31204 RW=2080 ZI=152152),
RAM 预算门禁 PASS(RW_IRAM1 73.9%、RW_CCM 87.9%)。
2026-11-10 20:33:30 +08:00

9.7 KiB
Raw Blame History

Steps(自 SKILL.md 外置)

本文由 stale-doc-count-sweep 的 SKILL.md「Steps」一节逐字外置而来(渐进展开:主文件只留索引与指针)。步骤号沿用原文,未重编。

  1. 实测真值:先剔伪命中,再双源互证(不抄用户口述、不抄另一处文档)。逐数走上面那张表;两个来源对不上时先找分歧根因(把全部命中逐条打印出来看),不要取第一个、不要取平均,并在结论里写明分歧与取舍(实测:菜单 #page= 计数 29 对 注册表 28,根因是头部注释示例行)。

    cd "<repo>"
    ls simulator/tests/ref/shot_*.bin | wc -l                     # 张数(判据 = 入库实数)
    awk '/^PAGES = \[/,/^\]/' simulator/tests/check_content_pages.py | grep -cE '^ *\("'   # 页数(第二个来源,两者必须一致)
    grep -n '#page=' ui_menu_tree.txt | head -3                    # 先看首条是不是注释示例行,再定叶数
    grep -rn 'UI_PAGE_MAP_COUNT' Drivers/BSP/UI/ui_page_registry.h  # 已绑叶数(生成物)
    grep -c '\.bitmap_index' Drivers/BSP/UI/ui_font_cn_12.c         # 314 = 含 notdef;字形 = 该数 - 1
    & '.venv\Scripts\python.exe' -c "import yaml;d=yaml.safe_load(open('.pre-commit-config.yaml',encoding='utf-8'));print(sum(len(r['hooks']) for r in d['repos']))"   # 钩子数口径
    

    ⚠ 权威脚本输出乱码时(check_font_charset.py 在 GBK 代码页下整行打印成 U+FFFD 替换字符串 + : PASS,数字全读不出来),改为直接数源文件里符号出现次数(.bitmap_index / .range_start / 码点唯一化)——不许臆读乱码,也不许因此退回去抄文档里的旧数。

  2. 全形态 + 全命中面扫描。一个数一次列出它全部历史形态,别只扫当前旧值:本轮 = 122/217、179/274、185/280、47 → 53、53 → 60、PAGES = 53、UI_PAGE_MAP_COUNT = 22、已绑 22 叶、未绑 11、内容页 53 页。

    grep -rn --include=*.md --include=*.py --include=*.yaml --include=*.txt --include=*.c --include=*.h \
      -E '122 唯一字|217 字形|179 汉字|274 字形|185 唯一字|280 字形|47 → 53|53 → 60|内容页 53|PAGES = 53|UI_PAGE_MAP_COUNT = 22|已绑 22|未绑 11' . \
      | grep -v -E '^\./(ci-artifacts|\.mnemon|\.dsh/runs)/'
    

    命中面比「文档」宽,至少包含:docs/**、AGENTS.md、.pre-commit-config.yaml(钩子 name: 显示名内嵌页数:name: UI 像素回归(菜单 8 状态 + 内容页 60 页 黄金参考) 就是命中点)、scripts/*.py、simulator/**/README.md、以及 .dsh/skills/*/SKILL.md(本窗 font-regen 正文自带 179/274 计数,直到 step 150 才发现;编号门禁退役那轮 id-family-semantic-migration、task-worktree 两个 skill 正文与 scripts/README.md 同样是引用面)。

    先列出 文件:行:全文,判定前必须看整行——cut -c1-120 会截掉后半句(那里常写着日期戳或口径)。

  3. 逐条分类,五类各走各的路(本 playbook 的核心,别用一条规则套全部命中):

    类别 判定 动作
    当前态陈述 描述「现在是多少」 改成实测真值
    变更记录历史行 形如「47 → 53 页」的当日事实 原样冻结不回改——但这条只适用于保留变更记录的 5 篇真台账(台账 / 被别处当唯一证据出处的文档,清单 → docs/文档规范.md §5.1)与 scripts/archive/ 归档;其余文档没有变更记录节,不再追加任何流水行,数字同步只改当前态
    同数不同义 最坏路径 < 40KB 这类内存/绘制缓冲红线 不动,并在结论里写明「为什么不动」
    带日期戳的测量 「2026-10-26 实跑 …覆盖当时 40 页中的」 不臆改新数,只补「当时」两字锁口径;新数留待下次实跑回填
    数字对但口径描述错 数没错、句子把口径讲错了(实测:写「218 字(含 ASCII/符号,共 313 字形)」,而 ui_cn_chars.txt 的 218 个码点全为非 ASCII) 另起一笔只改口径的提交(6daa01ae),不与数字同步混笔;这类命中在任何数字 diff 里都看不见,只能把口径句逐句读一遍

    拿不准就回到第 2 步把整行打印出来再判;判错历史行 = 把当天事实改成假账。

  4. 每处先读现文,再逐条字面替换并断言命中数(弃用整文件正则批处理)。本窗两度返工都是没先读现文:step 45 断言 HIT 0 抛错(目标串与现文不一致),step 44 是脚本语法错。脚本写成临时文件再跑(内嵌 heredoc/模板字符串里的反引号会截断整脚本),按字节替换以保 BOM 与行尾不动:

    import pathlib, sys
    sys.stdout.reconfigure(encoding='utf-8', errors='replace')
    JOBS = [  # (文件, old, new, 期望命中数)
        ('AGENTS.md', '内容页 53 页黄金参考', '内容页 60 页黄金参考', 1),
        ('.pre-commit-config.yaml', '内容页 53 页 黄金参考', '内容页 60 页 黄金参考', 1),
        ('docs/架构设计/项目架构总览.md', '122 字/217 字形', '218 字/313 字形', 1),
        ('docs/UI设计/UI_自动化测试流程.md', '文本断言 **310 条**、覆盖 40 页中的', '文本断言 **310 条**、覆盖当时 40 页中的', 1),
    ]
    for path, old, new, expect in JOBS:
        p = pathlib.Path(path); raw = p.read_bytes()
        o, n = old.encode('utf-8'), new.encode('utf-8')
        got = raw.count(o)
        assert got == expect, f'{path}: 命中 {got},期望 {expect}(未写入)'
        assert o != n, f'{path}: old 与 new 相同'
        p.write_bytes(raw.replace(o, n))
        print(f'OK {path}: {old} -> {new} x{got}')
    

    每行打印 old -> new xN,收口时这串输出就是「改了哪几处」的账。脚本报错/没编译过,先 git diff --stat 确认零写入再换写法(不要在半落地状态上叠改)。

    • 反引号:TS 侧先用可见占位符(如 ~TB~)写文本,落盘前再还原成真反引号 —— const BT = String.fromCharCode(96); const q = s => s.split(TOKEN).join(BT)(本窗实测:直接把带反引号的串塞进模板字符串/heredoc,整批零落地或把变更记录行写坏)。用 tools.edit 批量改时同样先 await tools.read 现文再传 old_string;批量里若某条 old_string 与 new_string 相同会报 must differ —— 只有该条作废、其余已落盘,别整批重跑。
    • 历史行被写坏(反引号及紧随其后的字符经工具传递被吞 → 变更记录行只剩半行、尾部出现 ?? 这类残迹):立刻按无反引号兜底写法整行重写——裸词 accident / oper / alarm / start / yk、页面绑定写成不带反引号的 #page=——而不是拿同样带反引号的串再改一遍(实测连返工三次:step 81→82→83→85)。
  5. 一笔只装一类事。数字同步一笔(cbb4fdb8:11 处 + 变更记录一行);口径更正另起一笔(6daa01ae);提交后复扫逮到的漏网当前态再补独立一笔(11d60057)。钩子一增一减写成一个当日行的两个阶段(51 → 52 加 id-check-new、随即 52 → 51 摘 id-check),别写两行互相打脸。提交说明如实写(「先认一笔自己的错:上一笔的未绑 21 叶是探针错」),别把口径修正包装成「补充说明」。

  6. 被改文件全文通读,核对其余小节——不是只看 diff。同一文档内互相引用的小节必须一致(本窗产品需求:§2.4 立项未排、§5.14 FR-SOE-3、§8.2 绑定现状、§8.3 已绑分页表、§9.1 差距表、§9.2 顺序表六处同时引用这四个数;当窗口的 docs/任务规划/README.md 就同时有两处表引用同一批数,后来合成一张)。若发现上一笔自己写进文档的数口径就错了,明确认错并改正,同时把可复核的重算方法写进文档(「按缩进判叶子:有更深缩进后继者即非叶子」),防止再错。

  7. 提交后再复扫一遍(收尾硬步骤,不许省,也不许只在提交前扫)。按第 2 步的全部旧形态整仓再扫一次,逐条分类为 当前态 / 历史行 / 同数不同义:本窗 cbb4fdb8 提交后复扫得 14 条命中,12 条以上都在变更记录历史行(47 → 53、53 → 60、122/217 冻结),唯一残留的当前态命中是 docs/架构设计/项目架构总览.md §3「界面层」那行 → 单独补一笔 11d60057。说不出归属的就是漏改。

    grep -rn -E '22 叶|未绑 11|11 叶|53 页|122 唯一字|217 字形|185 唯一字|280 字形|内容页 53|PAGES = 53|UI_PAGE_MAP_COUNT = 22' \
      . | grep -v -E '^\./(ci-artifacts|\.mnemon|\.dsh/runs)/'
    
  8. 跑门禁、分笔提交(git commit 属 Ask first,须用户明确指示后再做):

    & '.venv\Scripts\python.exe' scripts/check_doc_links.py --all --sections-strict   # 期望「文档路径检查通过(N 个文档)」
    & '\.venv\Scripts\python.exe' scripts/archive/id_gate/check_ids_new.py --range A..B   # 编号形态普查(两道门禁 2026-10-28 / 2026-10-29 都已退役,不再是提交钩子)
    & '.venv\Scripts\python.exe' scripts/ci_local.py                                    # 或 pre-commit run --files <被改文件>
    

    PowerShell 形态把 ./.venv/Scripts/python.exe 换成 & '.venv\Scripts\python.exe'。提交信息一律 git commit -F <UTF-8 无 BOM 文件>,别用 -m(中文长标题易超 100 字符、终端代码页会转码);标题 ≤100、正文每行 ≤80(实测把正文压到 66/78 字符才过 gitlint)。