Commit c27f29f
`scan()` 原本只枚举 `git ls-files`,也就是索引。一个刚写出来、还没
`git add` 的文件根本不在扫描集里,门禁照样 exit 0 并打印它惯常的成功
行 —— 读起来是「这棵树没有裸控制字节」,而不是「你刚写的那个文件没被
看过」。
这个洞的形状恰好等于本门禁自己的事故源:每一例裸字节都来自编辑工具在
作者「正在写关于这个字节的内容」时把转义落成真字节(#4763 / #4890 /
PR #5140 / #5460 的 issue 正文),而落点必然是一个**新文件**。于是
agent 指令要求的那次「push 前跑一遍」,正是最可能在看一个索引枚举够不
到的文件的那次运行。#6984 实测过:一个未跟踪文件里躺着裸 0x1b,
AGENTS.md 的 self-scan 找得到,本门禁绿,唯一的差别是索引。
- 扫描集改为「索引 + `--others --exclude-standard`」,即 git 既不跟踪
也不忽略的工作区文件。
- 成功行改为同时报出两半:`scanned N text file(s) -- N tracked,
M untracked-not-ignored`。M 为 0 时**照样打印**,否则 CI 的绿和
#6984 之前那种绿会渲染成同一句话,而后者正是本单要消掉的假信心。
- 未跟踪的命中在报错行上标 `[untracked]`——「还没 add」是作者拿到
一个被拒文件后第一个需要知道的事实。
- `--list` 逐条列出未跟踪的那一半路径。
三项实测,不是断言:
1. `--exclude-standard` 让本地垃圾留在外面。本仓库在完整 `pnpm install`
之后,未跟踪路径 76122 条,过 `--exclude-standard` 之后 0 条;它是剪
枝而不是遍历,16ms vs 索引枚举的 5ms。EXCLUDED 仍叠加在上面,所以有
人把 node_modules 取消忽略也点不红。
2. CI 里是 no-op:workflow 检出的是一个 commit,全树受跟踪,未跟踪那一
半恒为空。`--self-test` 用「把样本 stage 掉再扫一遍」证明,而不是在
注释里声称。
3. 反向:回退 `enumerate()` 的未跟踪那一半,6 条新断言立刻转红。
`--self-test` 断言数 48 → 75。临时仓库额外把 `core.excludesFile` 指向
一个空文件,否则开发者的全局 ignore 会让「EXCLUDED 仍然生效」那条样本
因为另一个原因通过。
工具链改动,不涉及任何 package,不发版 —— 走 `skip-changeset`,与近期
scripts/ + workflow-only PR 的做法一致(#7048 / #7008 / #6983 / #6917)。
Claude-Session: https://claude.ai/code/session_01F8q5J1MQyocgtNspb15fSn
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
1 parent 9f7a7c2 commit c27f29f
2 files changed
Lines changed: 313 additions & 27 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
117 | 117 | | |
118 | 118 | | |
119 | 119 | | |
120 | | - | |
121 | | - | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
122 | 127 | | |
123 | 128 | | |
124 | 129 | | |
| |||
0 commit comments