Skip to content

[BUG][P1] 源码里的字面 NUL 字节让 grep 静默失明 —— 加闸 + 清 7 个存量 #760

Closed

Description

@jinjunnn

大白话

仓里有 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

  1. added
    type:bugSomething is incorrect or regressed
    prio:P1High-value near-term delivery
    on Aug 1, 2026
  2. jinjunnn commented on Aug 1, 2026

    @jinjunnn
    OwnerAuthor

    追加:这个类跨两个仓,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 / 等价入口),
    否则修好一边,另一边继续按同一机制制造新成员。

    已实证代价更新(第四次)

    1. #737 枚举被修正两次(15 → 17 → 18);
    2. alpha-code#704 一轮里同类出现两次(编排者只修实例未枚举类);
    3. 编排者写建票命令时又混进一个真 NUL,被工具拒绝;
    4. alpha-web#109 差点据零命中得出「测试被删了」的错误结论。

    第 4 条是最危险的形态:它不是让你漏看,是让你看到一个假的「没有」并据此下结论。

  3. added a commit that references this issue on Aug 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    prio:P1High-value near-term deliverytype:bugSomething is incorrect or regressed

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions