Skip to content

Commit 1c4de99

Browse files
os-zhuangclaude
andcommitted
docs(os-dev): 「Byte discipline」段的 binary-file 危害点名 NUL,其余字节改引门禁脚本头的三条 (#5579)
该段给出的唯一理由是「One raw control byte makes grep treat the whole file as binary: zero matches, no signal」——而这条只对 NUL 成立。在容器内独立复现(样本用 printf 生成,未粘贴裸字节;GNU grep 3.11 + ripgrep 14.1.0): U+0000 grep: binary file matches rg: binary file matches (found "\0" ...) U+0001 grep: 2:searchable line rg: 2:searchable line U+007F grep: 2:searchable line rg: 2:searchable line 即门禁扫描面里除 NUL 之外的每个字节(含 #5460 纳入门禁、#5577 补进自扫字符类的 DEL)都不会让文件被当成二进制。危害只写这一条的后果不是文字不精确:agent 写出一枚 非 NUL 控制字节、自扫命中后去核对指令,会发现唯一被陈述的判据不成立,从而把门禁的红 判成误报。 `scripts/check-nul-bytes.mjs` 脚本头早就把两侧分开论证好了(#5157 段),本次把散文 口径搬过去对齐: - binary-file / zero-matches 那条点名 NUL,并标明是实测结论; - 其余扫描面字节引脚本头写清的三条:渲染为空(代码对每个读者说谎)、两种拼写互不 命中(文件里是字节,不是你会去搜的转义文本)、事故源不挑字节值; - 补一句直接堵住上述推理:「不是 NUL、grep 还能搜到」永远不构成把门禁红或自扫命中 读成误报的理由; - 危害论证指向脚本头「引用它,不要重新推导」,不在此处再抄一遍论证细节。 顺带修同段两处陈旧: - 「this repo has paid four times」的硬编码计数改为免计数措辞——该族已多于四例, #5624 刚因同样的漂移把台账里的 sibling 计数改成不含数字的表达; - 「a `0x01` that `check:nul-bytes` does not scan for (#5157)」的现在时已错:#5157 正是把该字节纳入扫描面的那一单,改为过去时的事实句。 未做(留档而非顺手扩面):单源化——让字符类与危害论证不再手抄多处——是 #5484 正文 留下的方向,本 PR 只修散文口径,不动 `scripts/check-nul-bytes.mjs`、不动 #5577 刚 补的自扫字符类、不动 #5630 刚加的 Toolchain traps 条目。 纪律:全程未向任何文件写入裸控制字节,散文沿用该文件与脚本头既有的 `0x01`/`0x7f` 十六进制写法(不含反斜杠转义,不会被编辑工具 materialise)。 `node scripts/check-nul-bytes.mjs` 绿;改动文件自扫 `grep -naP '[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]'` 无命中;`cat -A` / `od -c` 复核新增 行无意外字节。 `.claude/` 文档-only,无用户可见变更,走 skip-changeset 标签路线。 Fixes #5579 Claude-Session: https://claude.ai/code/session_01GX3sL71LFq8m2usg6VqTSE Co-authored-by: Claude <noreply@anthropic.com>
1 parent 4658e57 commit 1c4de99

1 file changed

Lines changed: 17 additions & 7 deletions

File tree

.claude/agents/os-dev.md

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -270,13 +270,23 @@ backslash-u forms like `\u0000` / `\u0001` — never as raw bytes, in **any**
270270
file (source, markdown, fixtures) and in any prompt or tool payload you
271271
compose: describe the escape, do not paste the byte. Editing tools
272272
materialize escapes into real control bytes precisely when you are writing
273-
*about* them — this repo has paid four times: #4763 (raw NUL in a dispatch
274-
prompt), #4890 (a raw NUL landed in `SKILL.md` **while writing the
275-
no-raw-NUL rule**, outside every gate's scan surface), and PR #5140's two
276-
bytes — a NUL plus, 14 bytes away, a `0x01` that `check:nul-bytes` does not
277-
scan for (#5157). One raw control byte makes grep treat the whole file as
278-
binary: zero matches, no signal, and the rule you just wrote becomes
279-
invisible to every agent that greps for it. Run
273+
*about* them, and this repo has paid for it repeatedly — including #4763
274+
(raw NUL in a dispatch prompt), #4890 (a raw NUL landed in `SKILL.md`
275+
**while writing the no-raw-NUL rule**, outside every gate's scan surface),
276+
and PR #5140's two bytes: a NUL plus, 14 bytes away, a `0x01` that the
277+
then-NUL-only scan walked straight past — the gap #5157 closed by widening
278+
the scan surface beyond NUL. The harms are argued in the gate script's
279+
header (`scripts/check-nul-bytes.mjs`) — cite it, don't re-derive it.
280+
Measured, only a raw **NUL** makes grep and ripgrep treat the whole file as
281+
binary and report zero matches with no signal, so the rule you just wrote
282+
becomes invisible to every agent that greps for it. Every other scanned byte
283+
(`0x01`, `0x7f`, …) keeps matching line by line, and is rejected for the
284+
three harms that land on the whole set: it **renders as nothing**, so the
285+
code lies to every reader; it is unfindable in **both** spellings, since the
286+
file holds a byte and not the escape text you would search for; and the
287+
accident source **does not pick byte values**. "Mine is not a NUL and grep
288+
still finds my file" is therefore never a reason to read a gate failure or a
289+
self-scan hit as a false positive. Run
280290
`node scripts/check-nul-bytes.mjs` before pushing, and when your change so
281291
much as *mentions* control characters, self-scan beyond the gate
282292
(`grep -naP '[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]' <files>`) — the gate's blind

0 commit comments

Comments
 (0)