The only rule in this repo that REJECTS a createSafeTranslation defaults row whose key no locale pack defines is one case of packages/app-shell/src/__tests__/defaults-maps-mirror-en-pack.test.tsx (objectui#4401), "every row names a key the en pack actually defines". Its own comment says what it is for:
Not an exception, a finding: a row whose key the pack lacks means the provider path cannot serve this string at all (i18next answers with the call site's defaultValue, or the raw key), so the two paths disagree by construction. Measured 0 across all three maps when this gate landed - if this goes red, file it rather than adding the key to an allow-list.
All three maps is the whole point: MAPS is a hand-written list of exactly three entries, pinned by expect(MAPS).toHaveLength(3) -
plugin-detail DETAIL_DEFAULT_TRANSLATIONS
plugin-list LIST_DEFAULT_TRANSLATIONS
plugin-designer DESIGNER_DEFAULT_TRANSLATIONS
Every other defaults table in the repo is outside it. packages/i18n/src/__tests__/fallback-placeholder-spelling-3512.test.ts measures that population one gate over, for a different rule (placeholder spelling): 31 createSafeTranslation tables, 762 string rows, DISCOVERED rather than listed, plus a three-entry registry of hand-rolled tables (GANTT_DEFAULT_TRANSLATIONS, IMPORT_DEFAULT_TRANSLATIONS, TIMELINE_DEFAULT_TRANSLATIONS). So the discovery mechanism this gate would need already exists, in a sibling file, walking the same tables with the TypeScript AST.
The evidence that this gap is load-bearing
objectui#7874: five timeline.relative.* rows sat in TIMELINE_DEFAULT_TRANSLATIONS with no en leaf and no call site anywhere. They were invisible to check-i18n-call-site-keys (judges call sites), to all-locales-key-parity (compares packs to each other), and to check-i18n-dead-keys (sweeps pack keys). They were NOT invisible to the rule quoted above - that rule names exactly this defect - the table simply is not in its list. They surfaced only because objectui#7567's census printed its abstention count.
What this is NOT
Not a duplicate of objectui#7567 / PR objectui#7870. That census's factory-default-drift class reads the same rows and deliberately ABSTAINS when en defines no value, because with no en value there is nothing to compare against; the objectui#7874 ruling is explicit that the abstention is correct and must not be turned into a comparison. This finding is about the other gate - the one whose verdict is already "a row with no pack key is a finding" - covering 3 tables instead of the discovered set.
Sizing, deliberately not done here
Whoever takes this should first run the extended population and REPORT the count before enforcing it: how many rows across the discovered tables have no en leaf today, and which of them are residue (delete) versus never-wired features (a card each). After objectui#7874 lands, the timeline table contributes 0 - it was the entire abstention bucket, 5 of 846 factory rows.
Landing surface is probably defaults-maps-mirror-en-pack.test.tsx itself, plus whatever the discovery needs to avoid inverting package dependencies - fallback-placeholder-spelling-3512.test.ts states that boundary for its own case (it reads source files as text rather than importing plugin packages, which is why it can live in @object-ui/i18n).
Filed by the os-dev seat while landing objectui#7874, session https://claude.ai/code/session_01KbJQ1y1J12nZxYzFWhP8Q3 . No assignee - PM triage.
Generated by Claude Code
The only rule in this repo that REJECTS a
createSafeTranslationdefaults row whose key no locale pack defines is one case ofpackages/app-shell/src/__tests__/defaults-maps-mirror-en-pack.test.tsx(objectui#4401), "every row names a key the en pack actually defines". Its own comment says what it is for:All three maps is the whole point:
MAPSis a hand-written list of exactly three entries, pinned byexpect(MAPS).toHaveLength(3)-plugin-detail DETAIL_DEFAULT_TRANSLATIONSplugin-list LIST_DEFAULT_TRANSLATIONSplugin-designer DESIGNER_DEFAULT_TRANSLATIONSEvery other defaults table in the repo is outside it.
packages/i18n/src/__tests__/fallback-placeholder-spelling-3512.test.tsmeasures that population one gate over, for a different rule (placeholder spelling): 31createSafeTranslationtables, 762 string rows, DISCOVERED rather than listed, plus a three-entry registry of hand-rolled tables (GANTT_DEFAULT_TRANSLATIONS,IMPORT_DEFAULT_TRANSLATIONS,TIMELINE_DEFAULT_TRANSLATIONS). So the discovery mechanism this gate would need already exists, in a sibling file, walking the same tables with the TypeScript AST.The evidence that this gap is load-bearing
objectui#7874: five
timeline.relative.*rows sat inTIMELINE_DEFAULT_TRANSLATIONSwith noenleaf and no call site anywhere. They were invisible tocheck-i18n-call-site-keys(judges call sites), toall-locales-key-parity(compares packs to each other), and tocheck-i18n-dead-keys(sweeps pack keys). They were NOT invisible to the rule quoted above - that rule names exactly this defect - the table simply is not in its list. They surfaced only because objectui#7567's census printed its abstention count.What this is NOT
Not a duplicate of objectui#7567 / PR objectui#7870. That census's
factory-default-driftclass reads the same rows and deliberately ABSTAINS whenendefines no value, because with noenvalue there is nothing to compare against; the objectui#7874 ruling is explicit that the abstention is correct and must not be turned into a comparison. This finding is about the other gate - the one whose verdict is already "a row with no pack key is a finding" - covering 3 tables instead of the discovered set.Sizing, deliberately not done here
Whoever takes this should first run the extended population and REPORT the count before enforcing it: how many rows across the discovered tables have no
enleaf today, and which of them are residue (delete) versus never-wired features (a card each). After objectui#7874 lands, the timeline table contributes 0 - it was the entire abstention bucket, 5 of 846 factory rows.Landing surface is probably
defaults-maps-mirror-en-pack.test.tsxitself, plus whatever the discovery needs to avoid inverting package dependencies -fallback-placeholder-spelling-3512.test.tsstates that boundary for its own case (it reads source files as text rather than importing plugin packages, which is why it can live in@object-ui/i18n).Filed by the
os-devseat while landing objectui#7874, session https://claude.ai/code/session_01KbJQ1y1J12nZxYzFWhP8Q3 . No assignee - PM triage.Generated by Claude Code