## 大白话 仓里有 7 个源文件含**字面 NUL 字节**。后果不是运行时错误,是**验证手段有盲区**: 普通 `grep` / `rg` 会把这些文件当二进制**静默跳过**,于是「我 grep 过了,没有」是假的。 本仓 `CLAUDE.md` 明写「大文件 `Edit` 后必须 `grep` + `git show` 双验」, 而在这些文件上 `grep` 会安静地说「没有」。 ## 已实证的代价 - **`#737`**(消除宿主为契约写的替身)的枚举因此被修正**两次**(15 → 17 → 18)。 当时 `rg -a` 才报出两个额外生产文件:`alpha-builtin-policy.ts` 与 `ext-manifest-v2.ts` —— **两个都在下面的清单里,至今没修**。 - **2026-08-01(`#704`)**:`package-alpha-connection.test.ts` 里的一个字面 NUL 让 `grep -c 'AlphaConnectionRecords'` 返回 exit 1 零输出,而文件里实际有 16 处。 编排者当时**只修了实例、没有枚举整类**,第二个实例由实现方在下一轮才发现。 - **建这张票时**,编排者写建票命令又带进一个真 NUL,被工具拒绝 —— 这类字符**极易在传递中混入**。 ## 全仓枚举(2026-08-01,字节扫描 4325 个源文件) | NUL 数 | 文件 | | --- | --- | | 2 | `packages/ui-mac/src/main/alpha-builtin-policy.ts` | | 1 | `packages/ui-mac/src/main/ext-install-planner.ts` | | 1 | `packages/ui-mac/src/main/ext-manifest-v2.test.ts` | | 1 | `packages/ui-mac/src/main/ext-manifest-v2.ts` | | 2 | `packages/ui-mac/src/renderer/alpha-ui/composer-attachments-core.ts` | | 1 | `packages/ui-mac/src/renderer/alpha-ui/composer-autocomplete.tsx` | | 1 | `packages/ui-mac/src/renderer/alpha-ui/session-timeline/timeline-model.ts` | (`#704` 的两处已在 `d0d84767` / `0a1e3be9` 修掉,不在此表。) ## 本票的重点不是「修这 7 个」 **枚举对新成员默认放行,咽喉对新成员默认拒绝。** 修完这 7 个,第 8 个明天照样会出现, 而且照样没人发现 —— 因为发现它的唯一手段(grep)正是被它破坏的那个。 **所以本票的主交付物是一道闸**:源码文件不得含字面 NUL 字节。 ## Development plan 1. **先加闸**(主交付物):扫描版本控制下的源文件(`*.ts` `*.tsx` `*.mjs` `*.js` `*.json` `*.tsv` `*.sh` 等),命中字面 NUL 即红,报出文件与偏移。 接进 `bin/check` / `scripts/alpha-check.sh`(**不是新开 CI job**,按本仓纪律)。 错误信息要直接给修法:把字面 NUL 换成 `\u0000` 转义(运行时逐字节等价)。 2. **再清存量**:上表 7 个文件逐个替换为 `\u0000`。 ⚠️ 逐个确认语义等价 —— 区分 TS 字符串字面量、模板字面量、正则、以及 `.json`; 部分文件可能是**有意**用 NUL 测二进制处理,替换后运行时字节仍相同,但要跑该文件测试确认。 3. **更新 `docs/architecture/host-extension-package-contract-boundary.md`**: 该文档现在把「字节轴(`rg -a`)」写成必需的检索纪律。闸落地后这条纪律的**理由**变了 —— 不再是「仓里有 NUL 文件所以要 -a」,而是「闸保证没有,`-a` 是防御性冗余」。如实改写。 ## Acceptance and named gates - 新闸:**故意往任一源文件塞一个字面 NUL → 必须变红**(这条要自己实施一遍确认)。 - 存量清零:全仓字节扫描命中数 = 0。 - 被修改的每个文件,其所属测试仍绿(证明替换语义等价)。 - 闸进 `bin/check`,不是单独的 CI job。 ## Out of scope 不改这些文件的任何行为逻辑;不动 `rg -a` 已有用法(防御性冗余,留着无害)。 ## 出处 `alpha-code#704` 修复轮(2026-08-01)。编排者按「实例 vs 类」纪律做了全仓枚举, 但判定存量清理会动到本票不拥有的多个子系统,故单独立票。
Activity
jinjunnn commentedon Aug 1, 2026
追加:这个类跨两个仓,alpha-web 也有
2026-08-01,
alpha-web#109的实现方在alpha-web撞上同一个类:tests/package-compiler.test.mjs(第 754 行附近)含 4 个裸 NUL 字节—— 被当排序分隔符写成字面
\x00而不是\u0000转义。file判它为data,BSD grep 因此对整个文件静默返回空。grep "secret"得到 0 命中,差点据此得出「测试被删了」的错误结论,之后全程改用
grep -a。⇒ 本票的闸必须两个仓都加(alpha-code 与 alpha-web 各自的
bin/check/ 等价入口),否则修好一边,另一边继续按同一机制制造新成员。
已实证代价更新(第四次)
#737枚举被修正两次(15 → 17 → 18);alpha-code#704一轮里同类出现两次(编排者只修实例未枚举类);alpha-web#109差点据零命中得出「测试被删了」的错误结论。第 4 条是最危险的形态:它不是让你漏看,是让你看到一个假的「没有」并据此下结论。
[#760][CODE] 字面 NUL 字节立咽喉闸:让「我 grep 过了,没有」不再可能是假话 (#774)
[REQ-160][CODE] 每轮消息结束后上报云端(含 BYOK 与附件字节) (#1367)