Files
STM32F4-Base/.dsh/skills/task-worktree/reference/clean-room-measure.md
T
wandering1 f08b12a46c docs(技能渐进展开): 五个技能正文逐字外置到 reference/,主文只留索引与指针
按「主文留头量、深规程外置」重写本仓技能,全部是逐字搬移:
搬移前断言原文每条非空行必须出现在新主文或 reference 文件里,
0 丢失才落盘;步骤编号一律不重排(正文有「第 12 步」交叉引用);
每个切点保留原小标题 + 索引(加粗引导句与步骤标题)+ 指针行。

主文变化(上限口径 = 插件写侧 65536 字节,见上一笔 skill-size 钩子):
- id-family-semantic-migration 33392 -> 10968(17%),reference 3 篇
- stale-doc-count-sweep 19811 -> 6945(11%),reference 2 篇
- mem-budget 19963 -> 13042(19%),reference 3 篇
- keil-build 12917 -> 8879(14%),reference 2 篇
- task-worktree 72601 -> 28139(42%),reference 8 篇

task-worktree 本笔同时收录另一会话已写完的 C2/D/G 三节正文——那
三处手改与我的拆分落在同一份文件改动里,不可分离;其内容同样已
随 reference/ 外置,主文只剩标题、索引与指针。

外置语料合计 122211 字节 / 30 篇:围栏数逐篇为偶,无 BOM/CR/U+FFFD。
draw-diagram 与 serial-boot-test 脚本是另一会话的在飞改动,本笔未含。

skill-size 钩子在本笔首次真跑(前一笔无 .dsh/skills 文件可触发)。

gate: pre-commit 全绿(doc-links、id-check-new、check-yaml、
      skill-size、check-added-large-files);30 篇 reference 手工字节
      体检 clean;skill() 逐个复载确认加载的是拆分版。
2026-10-29 15:03:12 +08:00

5.1 KiB
Raw Blame History

D. 门禁指标异常增长 → 逐文件归因(把净室工作树当测量仪,主树全程只读)

场景(2026-10-27 实测):id-check 突然 FAIL「不可判定 1,178 > 上限 1,166」——比上一轮量到的 1,162 又涨了 +16, 而主工作树里同时压着 4 条在飞任务道的未提交改动。不许 stash / checkout / reset(那是搬动甚至丢弃别人未提交的工作, 项目级 Never;git status 一乱,整条道的现场就没了),不许改门禁脚本本身(它就是那把尺子,改了数字就不可信), 也别在脏主树里跑门禁(那测的是 4 条道 + 未跟踪文件的混合体,永远分不出谁)。正解:在仓库之外另起一棵 detached HEAD 的干净工作树当净室,一次只往里注入一份在飞文件,与基线差分即得每个文件的独立贡献。两步: 净室建树 → 单文件注入测量。

  1. 建净室 + 先落基线数(路径必须在仓库目录之外;铁律 7 对临时树同样成立——放仓内就污染 git status / pre-commit --all-files / 全库搜索):

@T3@bash MAIN="D:/Code/DTU Code/STM32F4-Base" # 主工作树绝对路径(含空格 → 变量整体加引号) WT="$MAIN/../_wt/und-attr" # 仓外同级 _wt/ 下;一次测量固定用同一个名字 rm -rf "$WT" 2>/dev/null git -C "$MAIN" worktree add --detach "$WT" HEAD >/dev/null 2>&1 || { echo WT_FAIL; exit 9; } git -C "$WT" status --porcelain # 应为空 "$PY" "$WT/scripts/archive/id_gate/check_ids.py" 2>&1 | tail -25 # ← 口径:id-check 钩子已于 2026-10-28 退役(脚本移入 scripts/archive/id_gate/),按该脚本自身默认参数跑;基线与注入用同一条命令 @T3@

  • --detach(不要 -b):净室没有分支、不写 _wt/.state/<ID>.json 台账 → 不占 MAX_CONCURRENT = 8 名额、不出现在 $TW list,也没人会被误指去对它跑 done(建与拆都不走 $TW new / $TW done)。
  • 能这么量的前提:该门禁只读仓库内文本。依赖本树构建产物的门禁(mem-numbers / mem-budget 要 .map) 在净室里必然报「找不到 .map 事实源」(见陷阱「新建工作树从未构建过」)——那类指标不能这么归因。
  • git status --porcelain 非空 = 有别人的未跟踪文件被带进净室 → 先 git clean -xdn 干扫(别去 n) 看清会删什么,只挪走多出来的那些再测;语料被污染出来的数字与 CI 不可比。
  1. 一次只注入一份在飞文件 → 跑同一个扫描器 → 与基线差分(得到的是每个文件的独立贡献,不是合计):

@T3@bash for f in "App/log/sys_log_mcu.c" "test/host/sys_log_mcu/sys_log_mcu_test.c" "docs/子系统设计/运行与自检记录设计说明.md"; do mkdir -p "$WT/$(dirname "$f")" cp "$MAIN/$f" "$WT/$f" # 拷进净室;主树那份只读、一字节不动 echo "== $f =="; "$PY" "$WT/scripts/archive/id_gate/check_ids.py" 2>&1 | tail -25 # ← 与第 1 步同一条命令 git -C "$WT" checkout -- "$f" # 只还原净室里自己刚拷进来的那份 done @T3@

实测:run_par.c / board_ui_nav.py / check_nested_comment.py / keil SKILL.md 各 +0, 而 log 道那三个文件 +6 / +8 / +2,合计正好 +16。Σ(逐文件增量) ≠ 观察到的涨幅 → 还有没被注入的 在飞文件,或存在文件间交互项,不许就此交卷。 3. 定性增量是哪一类字面量(只有「谁」没有「为什么」= 给不出可执行的改法):同一计数器在 HEAD 版与 在飞版各数一遍,差值才是新增行带来的(存量的不算这条道的账);再对新增行直接 grep。本次 16 处全是 裸形 「字母 T 累进数字 4」(T 在 scripts/archive/id_gate/id_registry.json 的 bare_check_letters 里,规范形态是连字符形), 全部落进 skip_bare_unmanaged —— 到这一步结论才配发给属主。 4. 闭合 + 复验主树一个字节没被污染:

@T3@bash git -C "$MAIN" worktree remove --force "$WT" # 净室里只有自己的拷贝、没有原件,--force 安全 git -C "$MAIN" worktree list # 不该再有 und-attr git -C "$MAIN" status --porcelain | sort # 与测量前逐行一致(测量前先存一份基线清单) @T3@

⚠ 上面第一行的前提是有条件的:树里混进了别人的在飞 / 未跟踪内容时「只有自己的拷贝」就不成立了, --force 直接拆等于替别人把唯一版本删掉 → 先走 E 节(全景 → 逐文件分桶 → 联接预扫 → 唯一残留先备份), 再回来执行本步;复验按 E 第 5 步做(拆前/拆后主树 status --porcelain -uall 行数必须相同)。 同一棵净室树的第二种用法:按指定 commit 只读构建出像 / 烧录验收——不搬动任何在飞改动,也不为台架 提前抢发一笔提交;构建与烧录都在这棵树里做(不在主树),仍受 bench / build 锁串行(铁律 3)。