Skip to content

finding(plugin-timeline/i18n): five timeline.relative.* defaults rows have no en key and no caller — invisible to every existing i18n gate #7874

Description

@os-sam

Found by the new factory-default-drift comparison in scripts/check-i18n-call-site-keys.mjs (objectui#7567 / PR objectui#7870), while sizing that rule's abstention bucket. Not fixed there: that card's file surface was the gate script and its test, and this is a runtime-package edit.

The rows

packages/plugin-timeline/src/useTimelineTranslation.ts:26-30, inside TIMELINE_DEFAULT_TRANSLATIONS:

'timeline.relative.today': 'Today',
'timeline.relative.tomorrow': 'Tomorrow',
'timeline.relative.yesterday': 'Yesterday',
'timeline.relative.inDays': 'In {{n}} days',
'timeline.relative.daysAgo': '{{n}} days ago',

Two facts, both checked on origin/main at 6bca0e4e8:

  1. No en leaf. packages/i18n/src/locales/en.ts defines no timeline.relative.* key. (It has timeline.bucket.* and timeline.scale.*, both fully defined and fully aligned; this one subtree is not there.)
  2. No caller, anywhere. git grep 'timeline\.relative' over the whole tree — sources, tests and JSON, node_modules and dist excluded — returns exactly these five declaration lines and nothing else.

So they render for nobody: fallbackT only reaches a row when some call site asks for its key, and none does.

Why no existing rule can see them

This is the part worth recording, because it is not an oversight in any one gate — it is a gap between three of them:

  • check-i18n-call-site-keys's missing-key class judges call sites. A table row with no call site has none, so class 1 is structurally unable to reach it.
  • all-locales-key-parity.test.ts compares packs to each other. Ten packs identically lacking a key is full parity, and full parity is green.
  • check-i18n-dead-keys sweeps in the other direction — pack keys with no call site — and these keys are in no pack to be swept.
  • The new factory-default-drift class reads the row, but abstains: a key en does not define is class 1's shape by construction, and the two classes are kept disjoint on purpose. What it does do is print the count, which is how these five surfaced at all. They are the entire abstention bucket: 5 of 846 factory-table rows on this tree.

The fix is a product question, not a mechanical one

Two readings, and picking one silently is the thing to avoid:

  • Dead — the relative-date labels were superseded (formatRelativeDate in @object-ui/core does this job now) and these rows are residue. Then the fix is deleting the five lines.
  • Never wired up — the timeline was meant to render relative dates through t() and the call sites were never written. Then the fix is adding the five keys to packages/i18n/src/locales/en.ts (which makes all-locales-key-parity.test.ts demand them in the other nine packs, which is the correct order) and calling them.

⚠️ Note the {{n}} holes in two of the rows: if the second reading is right, {{n}} is what fallbackT resolves and what objectui#3512 holds the copy to, so the spelling is already correct and should be kept as-is rather than renamed to {{count}} without checking what the call site would pass.

⛔ Do not "fix" this by making the new gate compare them anyway — with no en value there is nothing to compare against, and the abstention is correct.

Lands in: packages/plugin-timeline (and packages/i18n if the second reading wins).

Filed by the os-dev seat on objectui#7567, session https://claude.ai/code/session_01KbJQ1y1J12nZxYzFWhP8Q3. Channel: MCP issue_write — repo-scoped REST issue creation was refused by the sandbox classifier on this seat.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatfindingi18npm:dispatchedpriority:p3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions