Skip to content

fix(scripts): check-readme-exports names its population as TRACKED, plus the scripts/ population census - #7017

Merged
zhuangjianguo merged 1 commit into
mainfrom
claude/issue-6545-gate-population-census
Aug 31, 2026
Merged

zhuangjianguo merged 1 commit into
mainfrom
claude/issue-6545-gate-population-census

Conversation

@claude

@claude claude Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Fixes #6545

What this is

The card's graded remedy — "make the population explicit in the gates' output" — was already in place on the two gates the card named, and had been since the commits that introduced them. So this PR is the other half the grading required: the census across scripts/, plus the one gap it found.

The stale premise, measured

gate verdict line says tracked? since
check-control-bytes yes — scanned N tracked text file(s) 7c9a4e5e3, 2026-08-05 (the commit that introduced it)
check-vi-mock-specifiers yes — N tracked source file(s) e9e55524e, 2026-08-25 (the commit that introduced it)

Neither file has been touched since the card was filed (2026-08-26 10:09Z) — git log --since on both paths is empty. That is why the card's own evidence block already quotes tracked in both outputs: option 1 was satisfied before it was written.

The census

Framed as the card's real question — can this gate be asked about a file it will not open, and does its output admit that? — rather than a grep for git ls-files.

Nine scripts/ files shell out to git. Four use git ls-files as their judged population:

gate population named in the verdict?
check-control-bytes yes — N tracked text file(s)
check-vi-mock-specifiers yes — N tracked source file(s)
check-vi-mock-inherit yes — N tracked source file(s)
check-readme-exports no — N README(s) under packages/, a claim about the directory

Not in the population question, and why:

  • check-changeset-presence — already solved in the opposite direction: it runs git ls-files --others --exclude-standard over .changeset/*.md specifically to see untracked changesets, so that writing one and running the gate before staging is not a false red. Documented in the script: "Empty in CI, where the checkout has no untracked files." Prior art for widening a population where the gate is asking "did you write X".
  • check-skills-paths — reads the directory, not git ls-files, and says so in its own docstring. Untracked files are inside its population.
  • pm/check-half-states — uses git ls-files as a validation oracle for path tokens, not as a scan population. An unverifiable token is dropped by design, so the index under-reports rather than invents.
  • The commit-range family (check-changeset-presence, check-i18n-en-drift, check-changeset-overwrite, check-governed-queue-guard) has a sibling population question — a range cannot see an uncommitted edit — and both gates that print a census already name it: Compared the working tree with SHA (merge-base with origin/main) and No en value changed in this range.
  • The ~26 gates that walk the filesystem (readdirSync / glob) have the inverse exposure, not this one: they see untracked files.

The one gap, and the fix

check-readme-exports walks git ls-files -- packages/ twice (READMEs, and package manifests) but reported 43 README(s) under packages/. That phrasing is a filesystem claim, and as a filesystem claim it is false the moment an author writes a new README and has not staged it.

Measured on this branch — planting a real, untracked packages/census-probe-pkg/README.md and package.json, then reading the gate's own census through its exported scan():

RUN 1  clean worktree              readmes=43 packages=40
       verdict: 43 README(s) under packages/ (0 outside any package), 407 fenced block(s) ...

RUN 2  untracked README on disk    readmes=43 packages=40
       verdict: 43 README(s) under packages/ (0 outside any package), 407 fenced block(s) ...

Byte-identical. The gate was green about a README.md sitting under packages/ that it never opened.

The change is the sentence, not the population: the verdict now reads 43 tracked README(s) under packages/ and ... of 40 tracked package(s). Same walk, same counts, same exit codes. Plus a header section stating the blind spot, and the matching correction in content/docs/guide/ci-cd-pipeline.md, which also said "for every README.md under packages/".

⛔ Options 2 and 3 are not here

Widening the population to untracked files, or refusing to run on a dirty worktree, change what these gates mean. The census did not make either look right: the one gate where widening is genuinely correct (check-changeset-presence) already does it, deliberately and locally. No recommendation to escalate.

Tests

Union run on 728ddacb2, the branch head.

  • pnpm exec vitest run --maxWorkers=2 scripts/__tests__/ — 90 files, 2573 tests passed. The whole tree, not just the gate's own file: content/docs/guide/ci-cd-pipeline.md is pinned by ci-cd-pipeline-doc.test.ts, doc-version-claims, lint-workflow, merge-queue-reporting, dependabot-merge-gate, check-action-forward-parity, quick-reference-current-release-4143 and scripts-type-check.
  • Gates, each read from its own verdict line, exit code captured before any pipe: check:control-bytes, check:entry-guard, check:doc-fences, check:vi-mock-specifiers, check:vi-mock-inherit, check:shell-escape-residue, check:skills-paths, check:changeset-presence, check:changeset-fixed, check:changeset-no-major, check:changeset-overwrite — all exit=0.
  • pnpm run type-check:scripts — exit 0, and tsc --listFiles confirms the edited test file is one of the 153 files in that program (not excluded).
  • eslint --no-inline-config --format json on the two changed JS/TS files — 0 errors, 0 warnings. Narrowed, and the narrowing is measured: the file count is eslint's own (--format json, 2 records); the markdown file is reported by eslint itself as outside its population ("File ignored because no matching configuration was supplied"), so it is covered by check:doc-fences instead; and eslint.config.js declares no parserOptions.project / projectService, so with type-aware linting off this diff cannot move the verdict on any file it does not touch.

Reverse verification of the new pin — predicted direction RED, and RED is what happened. Reverting only the two wording changes in the committed scripts/check-readme-exports.mjs (mutation confirmed on disk: removed-text count 0, blob eea2eacd vs HEAD 19fe5855, re-confirmed still mutated after the run) fails exactly one test:

× names that population as TRACKED, so a green is not read as a claim about the directory (objectui#6545)
  AssertionError: expected '0 README(s) under packages/ (0 outsid...' to contain 'tracked README(s) under packages/'
  Test Files  1 failed (1) · Tests  1 failed | 46 passed (47)

The pre-existing census-shape pin stays green, which is correct — it pins the shape, not the population word. Restore leg proven by blob equality with HEAD (19fe5855) plus an empty git diff HEAD and empty git status --porcelain, not by an exit code. No build is involved: the test imports the .mjs source directly, so there is no dist/ that could serve a stale copy.

A first attempt at this ablation was void and is reported as such: the setup shell's EXIT trap restored the file when that call ended, so the following call measured the unmutated tree and reported a green that looked like a passing ablation. Redone with mutation, run, and both proofs inside one invocation.

Changeset: .changeset/6545-gate-population-census.md, empty frontmatter — no package source, no published contract, no runtime behaviour changes.


Generated by Claude Code

Both of the gate's walks are `git ls-files -- packages/`, but its verdict line
read "N README(s) under packages/" — a claim about the directory. A brand-new
`packages/<pkg>/README.md` that has not been `git add`-ed is outside the
population, so a local pre-flight run reports OK without ever opening it.

Measured: planting an untracked `packages/census-probe-pkg/README.md` left
`census.readmes` at 43 and produced a byte-identical verdict line. CI is
unaffected — a committed tree has no untracked files — so this is purely local
pre-flight legibility.

The population is unchanged; only the sentence describing it. Found by a census
of every `scripts/` gate enumerating with `git ls-files`: four use it as their
judged population, and this was the only one that did not say so.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GgDDqh6YnkXqsnVTCa7wHk
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

finding(scripts): check-control-bytes and check-vi-mock-specifiers scan TRACKED files only, so they print green on a new file they never opened

2 participants