Skip to content

docs(ci): 控制字节集合的最后两处散文手抄改为引用门禁脚本头 (#5681) - #6166

Merged
hotlong merged 1 commit into
mainfrom
claude/issue-5681-cite-header-lint-yml
Aug 7, 2026
Merged

docs(ci): 控制字节集合的最后两处散文手抄改为引用门禁脚本头 (#5681)#6166
hotlong merged 1 commit into
mainfrom
claude/issue-5681-cite-header-lint-yml

Conversation

@hotlong

@hotlong hotlong commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Fixes #5681

cite-the-header 族(#5579#5646)的收口单。同一批扫描字节此前有两类写法:可粘贴的 PCRE 字符类已被 #5646--self-test 锁住(与 IS_SCANNED 表的派生结果逐字节相等,漂移即红);散文枚举同一批字节的两处仍是人肉同步。本 PR 把这最后两处散文改成「引用 + 一句话摘要」。

按 issue 与分诊口径:CI 步骤注释的读者常常只在网页上看 workflow 文件、不会跳去读脚本,所以这里用「引用 + 一句话摘要」而不是 os-dev.md 那种纯引用;步骤名与**「作者应写转义而不是字节」这句 actionable 结论**原样保留。

站点 1:.github/workflows/lint.yml(「Raw control-byte guard」步骤注释)

立单时记为 :98,今晚 #5827 / #6079 落地后已漂移,按内容重新定位(现 :97 起)。

改前(26 行:逐字节枚举 + 三条危害论证的复述):

      # Raw control-byte guard (#3127 / #4890 / #5157 / #5460). Scans every
      # tracked TEXT file for a raw ASCII control byte — 0x00-0x08, 0x0b, 0x0c,
      # 0x0e-0x1f and 0x7f, i.e. everything except tab/LF/CR. Two distinct
      # harms, one gate:
      #   • A literal U+0000 makes grep/ripgrep treat the whole file as binary and
      #     silently return ZERO matches — the file drops out of code search and
      #     out of every grep-based lint, with no error saying so. Nothing else
      #     catches it: git sniffs only the first 8000 bytes to decide binary-ness,
      #     and protocol.ts carried its NUL at offset 147230, so it kept diffing as
      #     ordinary text through review. That blind spot let six files accumulate
      #     the same defect.
      #   • The other C0 controls still match in grep but RENDER AS NOTHING, so a
      #     load-bearing separator reads as an empty string in the diff and in
      #     review: `keyParts.join('<0x01>')` shows up as `keyParts.join('')`.
      #     Four tracked source files carried those past the NUL-only gate until
      #     #5157 widened the scan surface; PR #5140 is the case that found it,
      #     when a 0x01 sitting 14 bytes from a caught NUL went unfixed.
      #   • DEL (0x7f) is in the set for the same reason, added by #5460. It is
      #     not a C0 control — it sits alone past the printable range — so the
      #     C0-shaped set could not reach it, and two raw specimens survived in
      #     the CLI's password prompts nine lines below a 0x03 #5157 had just
      #     escaped, reading as `case ''`. The set is drawn by the accident
      #     source (a tool materialising an escape into its byte), and that
      #     source does not pick byte values.
      # The command name stays `check:nul-bytes` for continuity — see the script's
      # header for why. Authors must write the unicode escape instead of the byte.
      - name: Raw control-byte guard
        run: pnpm check:nul-bytes

改后(13 行:引用 + 一句话摘要;末两行与步骤本身原样未动):

      # Raw control-byte guard (#3127 / #4890 / #5157 / #5460). Scans every
      # tracked TEXT file for a raw ASCII control byte and fails on any hit.
      # WHICH bytes are in the set and WHY each is rejected are stated and argued
      # once, in the gate script's header — `scripts/check-nul-bytes.mjs`. That
      # header is authoritative and this comment cites it rather than restating it
      # (#5579 established the footing, #5681 applied it here). The one-line
      # summary, for whoever is reading this because the step just went red: the
      # set is every ASCII control character except tab/LF/CR, drawn by the
      # ACCIDENT SOURCE — an editing tool materialising an escape into its byte —
      # and not by byte semantics, so "mine is not a NUL" is never a reason to read
      # a hit as a false positive.
      # The command name stays `check:nul-bytes` for continuity — see the script's
      # header for why. Authors must write the unicode escape instead of the byte.
      - name: Raw control-byte guard
        run: pnpm check:nul-bytes

保留的那句摘要挑的是排查门禁失败时真正用得上的一条:集合按事故来源(编辑工具把转义实体化成字节)划定,而不是按字节语义 —— 所以「我这个又不是 NUL」从来不是把命中当误报的理由。逐字节清单与三条危害的完整论证留在脚本头,由它独家持有。

站点 2:scripts/check-nul-bytes.mjs 头部开篇行

⚠️ 这个文件的头部含有 #5646 锁住的可粘贴字符类行(「Equivalently」锚点 + 其下的 backtick 字符类)。该行逐字节未动,见下方反向验证。

改前:

// Scanned set (#5157, #5460): 0x00-0x08, 0x0b, 0x0c, 0x0e-0x1f and 0x7f -- every
// ASCII control character except the three bytes that ARE ordinary text
// structure: tab (0x09), LF (0x0a), CR (0x0d). Equivalently
// `[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]`.

改后(枚举塌缩为对下方权威行的引用;最后两行原样):

// Scanned set (#5157, #5460): every ASCII control character except the three that
// ARE ordinary text structure -- tab, LF, CR. The `IS_SCANNED` table below is the
// authoritative statement of which bytes those are; this line deliberately no
// longer transcribes the list (#5681), and the pasteable class on the next line is
// DERIVED from that table rather than copied (see "The character class is written
// down once" below). Equivalently
// `[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]`.

附带的一处措辞修正(同文件,同一条注释族)

CHAR_CLASS_REFERENCES 的台账注释里,解释「为什么这两处不登记」时把它们称作 prose ENUMERATIONS。本 PR 之后两处都不再枚举,不改则这条注释自身失真 —— 读者顺着它去看开篇行会找不到所谓的枚举,正是本 issue 要消除的那种误导。故做一处最小措辞修正(ENUMERATIONSSTATEMENTS,并注明 #5681 之后二者都已改为引用),不登记、不改判定逻辑。

零行为变更证明

git diff每一行改动都是注释行(YAML #、JS // 与 JSDoc *);过滤掉注释行后剩余的改动行为空:

$ git diff -U0 | grep -E '^[+-]' | grep -vE '^(\+\+\+|---)' \
    | grep -vE '^[+-][[:space:]]*#' | grep -vE '^[+-][[:space:]]*(//|\*)'
(空)

diff stat:

 .github/workflows/lint.yml  | 33 ++++++++++-----------------------
 scripts/check-nul-bytes.mjs | 20 ++++++++++++--------
 2 files changed, 22 insertions(+), 31 deletions(-)

步骤的 run: pnpm check:nul-bytes 未动(YAML 解析出的 step 对象逐字段核对如下);脚本的可执行代码行、IS_SCANNED 表、scannedCharClass() 全部未动;lint.yml 的其它任何步骤未动。

$ python3 -c "import yaml; ..."
lint.yml parses OK; jobs: ['lint', 'typecheck']
step found: 1 -> [{'name': 'Raw control-byte guard', 'run': 'pnpm check:nul-bytes'}]

反向验证 —— 先定方向,再跑

站点 2 改的正是紧贴 #5646 锁定行的那几行,所以要证明的不是「锁没响」,而是锁仍然是活的:若我的改动碰到了锚点词或字符类,它必须变红。两个方向都按预测落地。

A. 抹掉我编辑的那行末尾的锚点词 Equivalently → 预测:红(提取失败)。实测红:

✗ check-nul-bytes --self-test -- 1 failure(s)
  • scripts/check-nul-bytes.mjs: found no character class at the registered anchor
    (this header's own pasteable rendering of the scanned set). ...
    Expected to find: [\x00-\x08\x0b\x0c\x0e-\x1f\x7f]

B. 把锁定字符类里的 \x7f 去掉 → 预测:红(逐字节相等断言)。实测红:

✗ check-nul-bytes --self-test -- 1 failure(s)
  • scripts/check-nul-bytes.mjs (this header's own pasteable rendering of the
    scanned set) spells the scanned set as [\x00-\x08\x0b\x0c\x0e-\x1f], but this
    gate scans [\x00-\x08\x0b\x0c\x0e-\x1f\x7f]. ...

两次扰动均已还原,还原后自测回绿,diff stat 与扰动前完全一致。

门禁

门禁 结果
node scripts/check-nul-bytes.mjs --self-test(改前) ✓ 56 assertions over a temp git repo (real scan() path)
node scripts/check-nul-bytes.mjs --self-test(改后) ✓ 56 assertions over a temp git repo (real scan() path)
pnpm check:nul-bytes OK (scanned 5900 tracked text file(s); skipped 5 binary, 1 non-regular; no raw ASCII control bytes)
YAML 有效性 lint.yml parses OK; jobs: ['lint', 'typecheck']
pnpm check:workflow-status-functions OK (scanned 22 workflow file(s), 39 job(s), 21 job-level if:; 9 read needs.*.outputs.*, all naming a status function),自测 34 断言绿
pnpm check:type-check-coverage(它也对 lint.yml 断言) OK — 62/77 workspace packages type-checked,自测 22+11+11 case 绿
npx eslint scripts/check-nul-bytes.mjs 干净,exit 0
字节自扫(改动涉及控制字符,按 os-dev.md 越过门禁自扫) grep -naP '[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]' 两文件均零命中

自测断言数改前改后同为 56 —— 本 PR 不增删断言,只动散文。

不发版

改动面只有 .github/workflows/scripts/,且全是注释,无任何用户可见变化,故不写 changeset,走 skip-changeset 标签。


Generated by Claude Code

cite-the-header 族(#5579#5646)收口。同一批扫描字节此前有两类写法:可粘贴的
PCRE 字符类已被 #5646 的 `--self-test` 锁住(与 `IS_SCANNED` 表派生结果逐字节相等,
漂移即红),而散文枚举同一批字节的两处仍是人肉同步 —— 本次把这两处改成引用。

1. `.github/workflows/lint.yml`「Raw control-byte guard」步骤注释:删掉逐字节枚举
   (0x00-0x08 / 0x0b / 0x0c / 0x0e-0x1f / 0x7f)与三条危害论证的复述,改为引用
   `scripts/check-nul-bytes.mjs` 头部 + 一句话摘要。按分诊口径,CI 注释的读者常只在
   网页上看 workflow 文件、不会跳读脚本,所以是「引用 + 一句话摘要」而非纯引用;
   步骤名与「作者应写转义而不是字节」这句 actionable 结论原样保留。

2. `scripts/check-nul-bytes.mjs` 头部开篇行:同样删掉逐字节枚举,改为指向下方
   `IS_SCANNED` 表(权威声明)与 `scannedCharClass()`(派生而非抄写)。

顺带修正 `CHAR_CLASS_REFERENCES` 台账里描述这两处的措辞 —— 它原本称它们为
「prose ENUMERATIONS」,本次改动后两处都不再枚举,不改则该注释自身失真。

纯注释改动,零行为变更:`git diff` 中每一行改动都是注释行(YAML `#` / JS `//` 与
`*`),步骤的 `run: pnpm check:nul-bytes` 与全部可执行代码行未动。#5646 锁住的
「Equivalently」锚点行与其下的字符类行逐字节未动,`--self-test` 断言数 56 → 56 全绿。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BDmDsu2575gDxeMCxXhDE3
@vercel

vercel Bot commented Aug 7, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
objectstack Ignored Ignored Aug 7, 2026 4:44am

Request Review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

lint.yml 的控制字节集合仍是散文手抄:#5646 锁住了字符类字符串,散文枚举还剩一处未走 cite-the-header

2 participants