Skip to content

i18n: a corrected source description never reaches an already-translated locale, and no gate can tell the stale translation from a current one #9672

Description

@os-project-manager

Recording a gap surfaced while landing #9046 (PR #9669). Unassigned finding — not claiming, and not asserting a disposition.

Observed

When a field/object description or label is corrected in a .object.ts declaration, there is no mechanism that propagates the correction into a locale bundle that already holds a hand translation of the old text. The generated bundles keep the stale translation indefinitely, and every gate stays green.

The two halves, both measured on origin/main (d693ba158):

  1. Extraction deliberately will not overwrite it.packages/cli/src/commands/i18n/extract.ts merges against the committed bundles (mergeExisting: !flags['no-merge']), and only the default locale is filled from schema labels. --fill=default fills gaps — a stale-but-present string is not a gap, so it is skipped. This is correct behaviour on its own terms: the alternative (--no-merge) wipes every hand translation in the bundle, which is the incident that config's own comment warns about.

  2. check:i18n cannot see the drift. It proves the keys are in sync — that no authoring key is undeclared and no bundle carries an orphan. It never compares a translated value against the meaning of its source. So a locale asserting the opposite of what the English now says reports "all bundles in sync."

Why it is worth a card

This is the same shape as the class #9046 belongs to: a declared surface with no enforcement keeping it true. The locale bundle asserts a description to every non-English reader; nothing verifies that assertion still matches the source it was translated from. On compliance-adjacent text this is not cosmetic — #9046 existed precisely because two column descriptions promised a recertification review that does not happen, and three of the four locales would have kept promising it after the English was fixed, with check:i18n green throughout.

The correction in #9669 reached the three localized bundles only because a human edited the help leaves in place — the maintenance path the generated bundle header itself names ("Edit translations in place; re-run extract (with --merge) to fill new gaps. Do not hand-edit the structure — only the leaf string values."). That path works, but it is unenforced and invisible: nothing distinguishes "translator corrected it deliberately" from "nobody noticed."

What is genuinely open

⛔ I am not asserting this is a defect. It may be intended — translation staleness is normally a human/translator workflow concern, and a repo that regenerated translations automatically would be making a worse trade. The open question is whether it is intended and accepted, or an unnoticed hole:

  • If accepted, the honest close is to say so where it is discoverable — the extract config comment and the bundle header describe the merge behaviour but not its consequence for changed sources.
  • If a hole, the tractable shape is a staleness marker rather than a re-translation mechanism: record the source-text hash a translation was made from, and let check:i18n report the leaves whose source has moved since. That names which strings need a translator without touching any of them, and it does not degrade a locale to English to fix a promise.

⛔ Scoped honestly: such a check would be a translation-staleness detector for schema-derived strings, not coverage of "documentation that lies." It would not read prose in content/docs/**, JSDoc, or READMEs.

Related

Metadata

Metadata

Assignees

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions