Skip to content

fix(scripts): derive the dead-keys pack-object importer population, pin its readings - #9047

Merged
baozhoutao merged 1 commit into
mainfrom
claude/issue-8752-importer-enumeration
Sep 10, 2026
Merged

baozhoutao merged 1 commit into
mainfrom
claude/issue-8752-importer-enumeration

Conversation

@baozhoutao

Copy link
Copy Markdown
Contributor

Fixes #8752

What was stale, re-measured on this branch

scripts/check-i18n-dead-keys.mjs's header section "The pack-object importers, enumerated" ships the command to re-derive its own class and then stated the result in prose — "19 matches today, of which these four".

I re-ran that command myself on 152f0a700 before writing anything. It returns 31 matches — 5 non-test, 26 test-only. Every premise the order carried is confirmed at my base:

premise mine
header still says 19, "of which these four" confirmed
the command's own result: 19 → 28 → 31 confirmed, still 31
the fifth importer is in the tree and the script names it nowhere confirmed — 0 mentions, against a control of 1 for a name the file certainly contains

The drift is the card's thesis demonstrating itself: written true, decayed in place, and the bullet list decayed with it, carrying four entries for a population of five.

The count is deleted, not corrected

Per the ruling, and following objectui#8606 / objectui#8629 on main: the total is removed from the prose, the header says in place why no total is stated there, and a new derivePackObjectImporters() runs the header's own pipeline so the CLI prints the split on every run. The only population anyone reads is now computed by the run that prints it.

…but the bullets stay, because a count cannot produce them

This surface differs from the two precedents in a way that matters: each bullet says what its importer's SHAPE means for the property-chain leg — covered by design, covered by luck, nothing at risk — which is a reading, not a population. So derived and read are pinned to each other instead:

  • ANALYSED_PACK_OBJECT_IMPORTERS indexes the bullets;
  • the test suite fails when it and the live population disagree in either direction;
  • and a further assertion requires each listed path to be spelled in the header, so pasting a path in to make the test green — reproducing exactly the defect the pin exists to catch — fails too.

A sixth importer now turns a test red by name instead of joining the silence. The failure this section had was never a wrong number; it was an unclassified reader.

The fifth importer's analysis — the real work on this card

packages/react/src/utils/nonGridRowCeiling.tsx dereferences the pack at render to supply a defaultValue beside a t() call, and both keys it reads are two segments. That makes it this tree's first instance of class 4 of the header's "What CONFIRMED does NOT guarantee": the property-chain leg returns null below three segments by design, and with the key boundary on (objectui#8701) the full-key probe refuses the property read too, because a dot on the left is what marks a longer key.

Measured on a fixture carrying only the property-read line, through the script's own textFootprint():

  • under today's boundary: no hit for either key;
  • with keyBoundary: false (the pre-boundary substring behaviour): a hit for both.

⇒ both legs are blind to that read. Nothing is at risk today, and the reason is a property of that FILE rather than of the leg: the same expression also spells each key literally as its t() argument, so the AST pass reads them directly and neither key is ever a candidate — verified against a real run, both absent from CONFIRMED and from NEEDS-REVIEW. Coverage by coincidence, and the header now says so rather than leaving a reader to infer it. Four tests pin that coincidence for this file, so templating a key or moving the default away from its call goes red instead of quietly going dark.

The class-4 note is annotated in the same spirit: its own measurement ("not one of them reads any of the keys the change re-tiered") stands, but it was taken over the four-item list, so it now reads as no wrong verdict was found rather than the population was complete.

Boundaries respected

⛔ No i18n key deleted, retired or re-tiered. ⛔ objectui#8701's boundary predicate untouched — what the leg accepts is byte-identical. ⛔ No test skipped, disabled or quarantined. ⛔ content/docs/releases/ untouched. The fifth importer establishes no liveness the leg cannot already see, so the order's stop-and-escalate condition did not fire.

Verification

check result
vitest run scripts/__tests__/check-i18n-dead-keys.test.ts 75 passed (11 new)
vitest run scripts/__tests__/ — the whole directory, the tightest correct scope for a scripts/** diff 139 files passed, 4131 tests, 2 skipped
node scripts/check-i18n-dead-keys.mjs exit 0; new section prints 5 non-test, 26 test-only, all five marked analysed
type-check:scripts exit 0
lint:root — run in full, not narrowed exit 0, 0 errors (32 pre-existing warnings)
check:control-bytes OK, 7239 tracked text files scanned
check:new-line-citations · check:shell-escape-residue · check:esm-specifiers · check:entry-guard · check:unreferenced-sources · check:comment-mask-corpus all exit 0

Every exit code above was captured before any pipe.

Changeset: the repo's presence gate was run and printed — "Compared the working tree with 152f0a7 (merge-base with origin/main): 2 file(s) changed, 0 of them published source of a package the release covers … No source or published contract of a released package changed in this range, so no changeset is owed." ⇒ none added.

Ablation — the pin is shown able to fail

Both legs mutated the committed file on disk, proved the mutation landed by blob hash and anchor grep counts, ran, then restored under a trap and proved the restore by blob-hash equality with HEAD plus an empty git diff HEAD.

  1. Drop the fifth entry from the pinned list, and put 19 matches today back in the prose → vitest exit 1, 2 failed | 73 passed: "EVERY non-test importer in the live population is analysed in the header" and "the header states no hand-written match count".
  2. Paste a path into the list with no bullet written for it → vitest exit 1, 2 failed | 73 passed: "EVERY analysed importer still exists in the live population" and "each analysed path is spelled in the header, so an entry cannot exist without its reading".

Direction was transition to red in both, as predicted before running.

Filed, not fixed here

Refs: objectui#9046 — observation-class, filed bare. Class 4 now has a live instance and this PR pins that one file against it, but the class has no detector: a future importer reading a two-segment key off a pack with no co-located literal arrives with nothing measuring it, and that reading looks derivable. Out of scope here, because it would change what the leg measures.

🤖 Generated with Claude Code

https://claude.ai/code/session_01FhBNJcLRZLe8M87VcUgpKr


Generated by Claude Code

…in its readings

`scripts/check-i18n-dead-keys.mjs`'s header section "The pack-object
importers, enumerated" ships the command to re-derive its own class and
then stated the result in prose — "19 matches today, of which these
four". The total was true when written and decayed in place: 19 in the
comment, 28 when the drift was filed, 31 when it was corrected. The
bullet list decayed with it, carrying four entries for a population of
five. An enumeration that names its own re-derivation command and then
goes stale is worse than one that never claimed completeness: a reader
who trusts the header skips the grep.

The count is deleted rather than corrected. `derivePackObjectImporters()`
runs the header's own pipeline and the CLI prints the split, so the only
population anyone reads is computed by the run that prints it.

The bullets stay hand-written, because what they say — what each
importer's shape means for the property-chain leg — is a reading no
derivation produces. Derived and read are pinned to each other instead:
`ANALYSED_PACK_OBJECT_IMPORTERS` indexes the bullets, and the test suite
fails when it and the live population disagree in either direction,
including when a path is listed with no bullet written for it. A sixth
importer now turns a test red by name instead of joining the silence.

The fifth importer gets its bullet, and it is the interesting one:
`packages/react/src/utils/nonGridRowCeiling.tsx` dereferences the pack at
render to supply a `defaultValue`, and both keys it reads are two
segments. The property-chain leg returns null below three segments by
design, and with the key boundary on the full-key probe refuses the
property read too. Measured on a fixture carrying only that read: no hit
under today's boundary, a hit under the pre-boundary substring
behaviour — both legs are blind. Nothing is at risk today only because
the same expression also spells each key literally as its `t()`
argument, so the AST pass reads them directly and neither is ever a
candidate. That is coverage by coincidence, not by the leg, and the
header now says so; it is also this tree's first instance of class 4 of
"What CONFIRMED does NOT guarantee", whose own measurement was taken
over the four-item list and is annotated accordingly.

No key, tier or boundary predicate is touched.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FhBNJcLRZLe8M87VcUgpKr
@github-actions github-actions Bot added the tests label Sep 10, 2026
@baozhoutao
baozhoutao marked this pull request as ready for review September 10, 2026 20:38
@baozhoutao
baozhoutao added this pull request to the merge queue Sep 10, 2026
Merged via the queue into main with commit 13372e1 Sep 10, 2026
34 checks passed
@baozhoutao
baozhoutao deleted the claude/issue-8752-importer-enumeration branch September 10, 2026 21:11
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(i18n): check-i18n-dead-keys' enumerated pack-object importer list is stale — a fifth non-test importer exists and is unanalysed

1 participant