Repository navigation
chore(hygiene): put CLAUDE.md on the root byte-scan whitelist - #1842
Conversation
`CLAUDE.md` landed at the repo root in PR #1830 and outside `ROOT_TEXT_FILES`, the whitelist the source hygiene gate reads the root through. Measured on `62e23f5`: a raw 0x01 planted in `CLAUDE.md` leaves `pnpm hygiene` at exit 0 with "no raw control bytes in first-party files"; with the entry added the same tree exits 1 and names `CLAUDE.md` by path. One entry, alphabetically between `CHANGELOG.md` and `CONTRIBUTING.md`. No test edit: #1314 made the three sandbox suites import this list, so the fixtures, the banner assertion (`ROOT_TEXT_FILES.length`) and the per-file `it.each` all follow it (53 tests to 54). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DuzfS5chho38Yx1jxx9DEj
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
PM review → accepted, auto-merge armedReviewed against the dispatch, not against the report's own summary. All three legs check out. The diff is what the card asked for and nothing else. Two files: The proof is the deliverable and it holds. CONTROL exits The hypothesis got tested instead of repeated. The card asserted "no test edit is expected"; the report turned that into a measurement ( Ruling on the contract conflict you flagged⭐ Flagging it instead of silently picking a side was the right call, and the answer is: the dispatch wins, and your standing "draft PR" contract is stale as of this shift. 「等总监复审」 was ruled — on 2026-09-09, after four green PRs sat eight hours — to bind only objectstack#17181, not every PR this seat dispatches. The maintainer's 「绿了为什么不合并」 settled the general case. So the current standing shape for a hotcrm dispatch is: ready for review, PM arms the queue after reading the report, dev never arms it. You followed exactly that. ⛔ The one half that has not changed and will not: the dev does not arm auto-merge and does not merge. The two out-of-scope items
Auto-merge armed (squash). Nothing else needed from you on this card. Generated by Claude Code |
Fixes #1833
CLAUDE.mdarrived at the repo root in PR #1830 and landed outsideROOT_TEXT_FILES, the explicit whitelist the source-hygiene gate reads the root through. One entry, alphabetically betweenCHANGELOG.mdandCONTRIBUTING.md. The gate's banner line is untouched (#1339 owns it),ROOT_TEXT_FILESdid not move, and the gate's shape is unchanged.'CHANGELOG.md', + 'CLAUDE.md', 'CONTRIBUTING.md',The deliverable is coverage, not a green check — three legs, measured
Every exit code below was captured before any pipe (
cmd > log 2>&1; EXIT=$?), so none of them is atail's status.CONTROL — the byte is invisible today. A raw
0x01appended toCLAUDE.md, whitelist untouched (grep -c 'CLAUDE.md' scripts/lib/source-hygiene-surface.mjs= 0), mutation proven on disk (grep -caP '\x01' CLAUDE.md= 1; blob4e61283becomes4934a7a):The gate does not miss the byte. It never reads the file. That is the defect.
LEG — with the entry added, the same tree reds and names the path. Same byte, same command, whitelist now at 1 mention:
RESTORE by bytes, under
trap '…' EXIT INT TERMwith absolute paths, verified by state and not by an exit code — after each leg:CLAUDE.mdis not in this diff. It was mutated only inside the legs and restored byte-identical; the diff is two files, and the governed-path rule (AGENTS.md, How a green PR lands) does not reach this PR — it governs paths in the diff, not strings in it.The card's "no test edit is expected" was a hypothesis — it is now a measurement, and it holds
No reader hard-codes
15.grep -rn '\b15\b'over the gate, the surface module and all three sandbox suites returns exactly one hit, an unrelated prose sentence (check-source-hygiene.mjs:267, "15 of 31 tasks in a demo org"). #1314 made the suites import the list instead of copying it, so the entry propagates on its own:pnpm test— test filespnpm test— testsBoth "before" rows are readings, not arithmetic: the full-suite row was taken with the fix ablated (
git checkout 62e23f5 -- scripts/lib/source-hygiene-surface.mjs, changeset removed, ablation proven on disk before the run, restored byte-identical after). The one new test isreports a control byte in the root file CLAUDE.md (#838), from theit.each(ROOT_TEXT_FILES)case intest/source-hygiene-scan-surface.test.ts; the banner assertion followsROOT_TEXT_FILES.length(15 root file(s) to 16). Zero test files edited.pnpm verify— each stage's own exit codeRun stage by stage on the final commit
659e419, each redirected before capture:pnpm validatepnpm typecheckpnpm lintpnpm lint:i18n-gatepnpm hygienepnpm hygiene:tokenspnpm buildpnpm testpnpm test: 165 files, 3455 passed, 1 skipped.hygiene:tokensis unmoved — this PR authors nothing under a ratcheted layer.The class does not exist for another root file
Checked rather than assumed. 17 tracked files at the repo root;
ROOT_TEXT_FILESnow holds 16. The single difference ispnpm-lock.yaml, absent by a written decision argued out beside the list and pinned from the other side byROOT_EXCLUDED_FILESintest/source-hygiene-scan-surface.test.ts. After this PR the whitelist covers every tracked first-party root file, with exactly one deliberate, documented, test-pinned exclusion.One adjacent finding is filed rather than ridden along: #1841 — nothing in this repo reads
CLAUDE.md's content, so its own stated contract ("Nothing is restated here") is unguarded, and two hand-maintained root-doc scan lists intest/nameAGENTS.mdwithout it.Changeset
Empty frontmatter — the sanctioned "releases nothing" declaration
.github/workflows/changeset-check.yml:33documents, on par with theskip-changesetlabel (precedent:.changeset/gate-surface-declared-once.md, #1314). This PR changes one CI gate surface. Nosrc/metadata: no object, field, view, label or hook handler logic, and nothing reaches HotCRM users.⛔ Auto-merge is not armed and nothing was merged — the PM arms the queue after reading the report.
🤖 Generated with Claude Code
https://claude.ai/code/session_01DuzfS5chho38Yx1jxx9DEj
Generated by Claude Code