Repository navigation
fix(scripts): derive the dead-keys pack-object importer population, pin its readings - #9047
Merged
Merged
Conversation
…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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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
152f0a700before writing anything. It returns 31 matches — 5 non-test, 26 test-only. Every premise the order carried is confirmed at my base: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 newderivePackObjectImporters()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_IMPORTERSindexes the bullets;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.tsxdereferences the pack at render to supply adefaultValuebeside at()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 returnsnullbelow 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():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
vitest run scripts/__tests__/check-i18n-dead-keys.test.tsvitest run scripts/__tests__/— the whole directory, the tightest correct scope for ascripts/**diffnode scripts/check-i18n-dead-keys.mjs5 non-test, 26 test-only, all five markedanalysedtype-check:scriptslint:root— run in full, not narrowedcheck:control-bytescheck:new-line-citations·check:shell-escape-residue·check:esm-specifiers·check:entry-guard·check:unreferenced-sources·check:comment-mask-corpusEvery 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
HEADplus an emptygit diff HEAD.19 matches todayback 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 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