test(devx): check-nul-bytes 的 --self-test 断言字符类引用面逐字节相等,终结该族漂移 (#5646) - #5680
Merged
Merged
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
os-zhuang
marked this pull request as ready for review
August 6, 2026 00:03
This was referenced Aug 6, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #5646
字符类此前是手抄关系:
IS_SCANNED表是门禁真正扫的东西,而.claude/agents/os-dev.md「Byte discipline」段的自扫命令行里躺着一份手写副本。该族漂移当日已付两次 —— #5577(自扫类缺\x7f,门禁侧从 #5460 起早已纳入)与 #5579(危害论证只搬了对 NUL 成立的那条)。#5579 把散文侧改成「cite the header」(少一层重复),但字符类不能这么办:作者需要一条能直接粘的命令行。所以反向处理 —— 派生 + 断言。修法
scannedCharClass()从IS_SCANNED表派生出 PCRE 字符类(逐字节由字节值拼出,不写字面量 —— 本文件在自己的扫描面内)。--self-test新增一条检查:CHAR_CLASS_REFERENCES里登记的每处引用,提取出的字符类与派生结果逐字节相等;不等即红,失败信息同时打印两种拼写与「该粘贴哪一个」。比较是逐字节而非语义:
\x0b-\x0c与\x0b\x0c匹配同一批字节,但前者会判红。所以scannedCharClass()里的折叠约定(连续 3 字节以上收成区间,1–2 字节逐个写)是承重的 —— 必须有一个规范拼写,而它就是这个函数。为防「emitter 稳定但错」,另加一条:把派生出的类编译成真 RegExp、跑遍 0–255,选中的集合必须与表完全一致。引用面台账(全仓实测)
git grep 'x00-'与git grep 'grep -naP'全仓共 9 处命中,登记 2 处:.claude/agents/os-dev.md:311grep -naP之后的引号串)scripts/check-nul-bytes.mjs:9.changeset/control-byte-gate-scans-all-c0.md\x7f).changeset/control-byte-gate-scans-del.mdpackages/plugins/plugin-auth/CHANGELOG.md、.changeset/isLikelyEmail-no-control-char.md[^\x00-\x7f]scripts/check-nul-bytes.mjs:6、.github/workflows/lint.yml:98.claude/skills/pm-dispatch/SKILL.md、scripts/check-workflow-status-functions.mjs:291取舍口径:只锁受众是 agent 指令、可直接粘贴的活引用;历史记录类文本反而必须允许「过时」。台账写死在脚本里,新增引用处需登记 —— 与仓内 shrink-only 门禁的「显式列表」惯例同构。
提取锚点刻意不含字符类本身:含了的话,它会在正要抓的那次漂移上停止匹配,把「不相等」(能报出两种拼写)降级成「提取不到」(报不出)。
先红后绿(四个方向,均前台实测)
预期方向:引用面被改动即红。四种都是漂移,四种都必须红。
\x7f改成\x7e):✗ … .claude/agents/os-dev.md (the byte-discipline self-scan command line) spells the scanned set as [\x00-\x08\x0b\x0c\x0e-\x1f\x7e], but this gate scans [\x00-\x08\x0b\x0c\x0e-\x1f\x7f].exit=1 → 还原后 56 断言绿。\x7f):同一条断言判红,报出[\x00-\x08\x0b\x0c\x0e-\x1f]—— 正是当初漂了数月的那一版。grep -naP命令行删掉):✗ … found no character class at the registered anchor (the byte-discipline self-scan command line). Either the class was removed -- then de-register it … Expected to find: [\x00-\x08\x0b\x0c\x0e-\x1f\x7f]exit=1。⛔ 不静默跳过(check:react-declaration-parity 是唯一没接进任何 workflow 的源码审计门禁,且无 MANIFEST 时静默 skip 退出 0 —— 它现在永远不可能红 #4690 反模式)。… is a registered character-class reference but could not be read -- restore it, or remove it from CHAR_CLASS_REFERENCES on purposeexit=1。另两条旁证:未来扩面场景(往表里加一枚字节、两处引用都忘改)一次报出 4 条失败,其中两条分别点名 os-dev.md 与脚本头并给出新的规范拼写;语义相同、字节不同(
\x0b-\x0c)照样判红,坐实逐字节口径。权威方向与 os-dev.md 零改动
脚本
IS_SCANNED表是权威。实测两处当前已经一致(#5577 修完至今未再漂),所以本 PR 的os-dev.md改动为零 —— 文件面只有scripts/check-nul-bytes.mjs(+175/-0)。若实测到漂移,跟改会朝脚本对齐。边界
pnpm check:nul-bytes是--self-test再接全仓扫描,所以这条新断言天然进 CI 门禁。import.meta.url解析,cwd 骗不了它。scripts/门禁改动,不发布任何包 → 走skip-changeset标签路线(⛔ 不写空 frontmatter changeset,空 changeset 会静默卡死已 version 的发布:Release run 全绿,但 npm 和 Docker 什么都没发(17.0.0-rc.2 现在就卡着) #4898)。Generated by Claude Code