Skip to content

docs(check-links): state the scan populations instead of copying their counts - #7885

Merged
os-sam merged 1 commit into
mainfrom
claude/issue-7825-check-links-header-counts
Sep 6, 2026
Merged

docs(check-links): state the scan populations instead of copying their counts#7885
os-sam merged 1 commit into
mainfrom
claude/issue-7825-check-links-header-counts

Conversation

@claude

@claude claude Bot commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Fixes #7825

check-links.yml's header stated two document counts as literals, and both had
drifted with nothing red over the whole distance. Per the ruling on the card, the
numbers are not re-aligned — they are removed, and the header states its
populations and points at the readings instead, so the drift becomes structurally
impossible rather than merely correct today.

Fresh readings, re-measured on current main (83fe6e741, this branch's base)

The card measured 17 / 184 at 900f8d995. Today, with the same walk the
workflow's own args block declares:

reading header used to say measured on 83fe6e741
find docs -type f \( -name '*.md' -o -name '*.mdx' \) | wc -l 15 17
find content/docs -type f \( -name '*.md' -o -name '*.mdx' \) | wc -l 183 184

Split, for the record: content/docs is 144 .mdx + 40 .md; the repo-root
docs/ tree is all .md. Independently corroborated in the same session by
check:shell-escape-residue's own verdict line, which walks the same tree and
reports content/docs: 184 file(s).

Both figures are unchanged from the card's, so the surrounding prose still
describes the same scan scope — the scope statement was accurate, only its two
sizes were not. That is what made the rewrite a prose fix and not a scope change.

What changed

1. .github/workflows/check-links.yml — the header. Both sentences the card
flagged are rewritten, per ruling ②, because both read present tense:

  • The live claim now names the populations — which trees, which extensions,
    and the apps/site/source.config.ts declaration the content tree comes from —
    and points at the two readings that produce the live figures (a find in any
    checkout, and Lychee's own run summary). No numeral qualifies a document
    population anywhere in the header any more.
  • The historical claim is rewritten as explicit past tense, PR-numbered, and
    carries no live numeral: "Until PR check-links.yml(Lychee)扫的是 docs/**(15 个文件),不是站点文档 content/docs/**(183 个文件) #3449 the args list named only the
    repo-root docs/**, so not one published page had ever been scanned".

2. scripts/__tests__/check-links-workflow.test.ts — the third copy of
#7448's pin,
in the home the card named, plus a fixture-backed control.

3. The same two counts, in the pin's own file header (in surface). The test
file's header carried the drifted counts word for word — "docs/ is 15 files of
INTERNAL material" and "the 183 files under content/docs/**". Both are in this
PR's binding file surface, both are the same defect class, and leaving one of the
two copies guarded while the stale twin sat in the file that guards it is how the
guarded one gets "corrected" back from the twin later. Both sentences are
rewritten to name the trees without sizing them, and the pin reads that header as
a second surface.

The pin, and why it is not a verbatim copy of its twins

The two #7448 twins (check-doc-fence-languages.test.ts,
check-doc-component-types.test.ts) match a numeral immediately adjacent to a
population noun. Run verbatim over this header before the fix, that pattern
reports one of the two live counts:

PRE-FIX check-links.yml header (origin/main 83fe6e741):
  twin  regex => ["183 files"]
  #7825 regex => ["15 INTERNAL documents","183 files"]
POST-FIX check-links.yml header:
  #7825 regex => []

"holds 15 INTERNAL documents" is a document count by any reading, and the
adjective between the numeral and the noun is all it took to score clean. The
twins' own docstrings state the intent as "a numeral DIRECTLY qualifying a
document-population noun", so the third copy implements that stated intent rather
than a new rule: up to two intervening words are allowed, and an issue reference
is excluded at the pattern level instead of by luck. The noun set is unchanged
from the twins.

Both twin workflow headers are clean today under both patterns, so this is a
latent gap in those two instruments, not a live falsehood on their headers. Filed
separately rather than fixed here — see below.

Positive control — the pin fails, then passes, on both surfaces

Ruling ③: a pin that cannot fail is not a pin. Four legs, one script, mutation
proved on disk before each reading and the restore proved against the HEAD blob
(script: an EXIT INT TERM trap restoring both files by absolute path).

leg tree vitest exit result
0 as committed 0 9 passed
A a count written back into check-links.yml's header 1 1 failed, 8 passed
A' restored 0 9 passed
B a count written back into the test file's own header 1 1 failed, 8 passed
B' restored 0 9 passed

Leg A, the pin naming itself:

injected text hits: 1   (expect 1)
deleted anchor hits: 0  (expect 0)
blob now 8f01928f0f4987f010511c2da22622afa93ed5c1 vs HEAD b43e568fc4ec3d9253d04bbcb975958308dcfce2
AssertionError: check-links.yml states a document count (17 INTERNAL documents).
  Nothing fails when it drifts, so it will. ... : expected [ '17 INTERNAL documents' ] to deeply equal []

Leg B, the second surface:

injected text hits: 1   (expect 1)
AssertionError: this test file's own header states a document count (184 files).
  ... : expected [ '184 files' ] to deeply equal []

Restore legs, proved rather than assumed:

RESTORE PROVEN: .github/workflows/check-links.yml == HEAD blob b43e568fc4ec3d9253d04bbcb975958308dcfce2; git diff HEAD empty
RESTORE PROVEN: scripts/__tests__/check-links-workflow.test.ts == HEAD blob 27d7777c99124084108a2e8c0f43b24e0b5dc30f; git diff HEAD empty

The pin's fixture table asserts the same power without a mutation: the two
pre-fix sentences of this header and the two the #7448 twins' headers carried are
fixtured as positives; the negatives are every number a workflow header
legitimately keeps — an issue reference, 04:17 UTC, one 502, node-version: 22, timeout-minutes: 10, "the third instance of the same shape", and
~297 site-absolute links, which is the near miss that decides how far the
pattern may reach past the numeral.

Confirmations the ruling asked for, quoted verbatim

Governed surface (⑤). .github/workflows/ is not governed; run anyway:

$ node scripts/check-governed-queue-guard.mjs --test .github/workflows/check-links.yml scripts/__tests__/check-links-workflow.test.ts
✅ NOT GOVERNED — 2 path(s) checked against 5 governed surface(s); none matched.
   An ordinary pull request: the normal review and merge-queue route applies.

#3653's by-command doc pin (⑤). Confirmed, not assumed. The pin in
ci-cd-pipeline-doc.test.ts compares the first-party commands in ci.yml's
run: steps against the page's job table. check-links.yml is a separate
workflow that runs no command at all — its single step is
uses: lycheeverse/lychee-action@v2 — and this PR adds and removes no ci
command, so no doc row is owed. ci-cd-pipeline-doc.test.ts is green in the run
below.

Changeset (⑥). Its verdict, obeyed verbatim, measured on this branch's final
tree:

$ node scripts/check-changeset-presence.mjs
Compared the working tree with 83fe6e741 (merge-base with origin/main): 2 file(s) changed,
0 of them published source of a package the release covers, 0 of them a manifest whose
published contract moved, 0 under a package changesets ignores, 0 changeset(s) added.
✅  No source or published contract of a released package changed in this range, so no changeset is owed.

Nothing owed, so nothing added — and per this repo's rule the skip-changeset
label is NOT applied here: it reads as a mechanism and is not one in objectui.

Clause-② stays no (⑦). Prose and tests only. The scan scope is decided by
the args glob list, which is byte-identical to origin/main; the three
pre-existing scope assertions are untouched and still green.

Verification

Run after the final commit a5b52c4fa, with git diff HEAD empty.

pnpm exec vitest run --project unit scripts/__tests__/ --maxWorkers=2
  Test Files  104 passed (104)
       Tests  3089 passed (3089)

pnpm run type-check:scripts                     exit 0, no diagnostics
  (--listFiles confirms check-links-workflow.test.ts IS in the program: 1 hit)
pnpm run lint:root                              exit 0 — 0 errors, 33 pre-existing
                                                warnings, none in a file this PR touches
pnpm run check:control-bytes                    ✅ OK (6380 tracked text file(s))
pnpm run check:shell-escape-residue             ✅ OK (206 file(s), 1309 fenced block(s))
pnpm run check:governed-queue-guard             OK self-test: 132 cases pass

scripts/__tests__/ is the union that owns every workflow and prose pin in this
repo, so it is the union this diff can move; the per-package turbo run lint /
turbo run type-check farm is untouched by a comment and a script test, and CI
runs it regardless.

Filed separately, not fixed here


Generated by Claude Code

…r counts

`check-links.yml`'s header stated two document counts as literals — the
repo-root tree "holds 15 INTERNAL documents" and "the 183 files the
published site is built from live in `content/docs/**`". Both had
drifted (17 and 184 today) and nothing went red over the whole distance,
because nothing fails on a stale number written in a comment. The same
two counts were duplicated word for word in the header of the test file
that pins this workflow.

Changing 15 to 17 and 183 to 184 reloads the same trap, so instead the
header now names its populations — which trees, which extensions — and
points at the two live readings (a `find` in any checkout, and Lychee's
own run summary). The historical half is rewritten as explicit past
tense, PR-numbered, and carries no live numeral.

A third copy of #7448's pin lands in the workflow's own test file and
reds on the next numeral that qualifies a document population. It reads
the test file's own header as well as the workflow's, and it allows an
adjective between the numeral and the noun: run verbatim over the
pre-fix header, #7448's regex reported only one of the two live counts —
"15 INTERNAL documents" scored as clean because a word sits between the
numeral and the noun it counts. A fixture table demonstrates both
directions.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KbJQ1y1J12nZxYzFWhP8Q3
@os-sam
os-sam marked this pull request as ready for review September 6, 2026 01:39
@os-sam
os-sam added this pull request to the merge queue Sep 6, 2026
Merged via the queue into main with commit c4e8586 Sep 6, 2026
31 checks passed
@os-sam
os-sam deleted the claude/issue-7825-check-links-header-counts branch September 6, 2026 01:55
os-sam pushed a commit that referenced this pull request Sep 6, 2026
…n numeral and noun

objectui#7448 landed the same document-count pin in two gate test files and
stated the rule in both docstrings as "a numeral DIRECTLY qualifying a
document-population noun". Both implemented it as strict adjacency, so a single
adjective inside the noun phrase defeated them.

Measured, not inferred. #7448's regex run verbatim over `check-links.yml`'s
header as it stood on origin/main at 83fe6e7 — a header carrying two live
drifted counts — reports one of the two:

  twin  regex => ["183 files"]
  third regex => ["15 INTERNAL documents","183 files"]

The count it scores clean is the one that had drifted furthest (15 against a
measured 17), because an adjective sits between the numeral and the noun.

This carries the third copy's pattern (objectui#7825, PR #7885,
`check-links-workflow.test.ts`) to both twins verbatim: up to two intervening
words, issue references excluded at the pattern level by a negative lookbehind
rather than by luck, noun set unchanged. No fourth spelling is invented. The
docstrings drop "DIRECTLY" — keeping it would only have inverted the same gap
between what the pin claims and what it does.

Latent, not live: both twin workflow headers are clean under both patterns on
today's tree, so this closes a proven hole rather than a live violation.

Part of objectui#7888

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

finding(gate): check-links.yml's header carries two hand-copied document counts that have drifted

2 participants