diff --git a/.changeset/engine-i18n-carveout-recorded.md b/.changeset/engine-i18n-carveout-recorded.md new file mode 100644 index 0000000000..1784dfa100 --- /dev/null +++ b/.changeset/engine-i18n-carveout-recorded.md @@ -0,0 +1,13 @@ +--- +--- + +Docs only (objectui#4662): records the `engine.*` carve-out where the i18n +conventions live — `packages/i18n/README.md` gains a "Scope" section stating +that the metadata-admin (Studio) namespace resolves through a module-local +`en`/`zh` table rather than the ten locale packs, why that is Phase 3f design +rather than drift (the server's `/meta/types` `label` is the primary path; the +table is the fallback), the two consequences (eight locales render English +there; the i18n gates cannot see the namespace by construction), and the +condition for revisiting it. `packages/app-shell/src/views/metadata-admin/i18n.ts` +gains a header note pointing at that section — a comment-only edit. No key was +migrated, no locale pack was touched, and no published behaviour changes. diff --git a/packages/app-shell/src/views/metadata-admin/i18n.ts b/packages/app-shell/src/views/metadata-admin/i18n.ts index 8b231a3c49..43b6ca4a22 100644 --- a/packages/app-shell/src/views/metadata-admin/i18n.ts +++ b/packages/app-shell/src/views/metadata-admin/i18n.ts @@ -37,6 +37,20 @@ * more machinery than the defect is worth). Follow it when adding a value; the * designer renders inside the console shell, so a `...` here lands on the same * screen as a `…` from the packs. + * + * ## The same posture, recorded on the i18n conventions side (objectui#4662) + * + * Everything above is this file's own account of why it exists. + * `packages/i18n/README.md`, section "Scope — the `engine.*` carve-out", states + * it from the pack system's end, where a reader looking for the translation + * conventions finds it, and adds the two facts this header does not spell out: + * only `en` and `zh` are covered, so the other eight shipped locales render + * English on these screens; and the i18n gates cannot see it by construction + * (key parity compares pack against pack, and `scripts/check-i18n-call-site-keys.mjs` + * skips this module by declaration). It also carries the condition for + * reopening the question, which is deliberately narrow: a stated demand for an + * admin console in a language other than `en` or `zh` — not a general wish for + * broader locale coverage. Keep the two records in step when either moves. */ import { useObjectTranslation } from '@object-ui/i18n'; diff --git a/packages/i18n/README.md b/packages/i18n/README.md index 4cca3f5b58..79757ff7df 100644 --- a/packages/i18n/README.md +++ b/packages/i18n/README.md @@ -135,6 +135,48 @@ isRTL('ar'); // true isRTL('en'); // false ``` +## Scope — the `engine.*` carve-out (metadata-admin / Studio) + +Not every user-facing string in this repository resolves through these packs. +The metadata-admin (Studio) surface — the metadata directory, the inspectors, +package management, the flow designer and their refusal messages — resolves its +`engine.*` keys through a module-local **two-locale** table in +[`packages/app-shell/src/views/metadata-admin/i18n.ts`](../app-shell/src/views/metadata-admin/i18n.ts): +a plain `Record` lookup over `en-US` and `zh-CN`, not an i18next namespace. +Roughly 1,300 keys per locale live there, and **no `engine.*` key exists in any +of the ten packs.** + +That is design, not drift — the file's header records it as "Phase 3f". The +server holds the primary path: the engine consumes `label` from the +`/meta/types` response, sourced from the platform's metadata-type registry. The +module-local table is a **fallback** for deployments with no translation bundles +configured, and the interim source of truth for Chinese until the platform's +`setup.translation.ts` ships zh-CN coverage. Copying the namespace into the +packs would duplicate strings whose primary source is a server response. + +Two consequences follow, and both are accepted rather than outstanding work: + +- **Only `en` and `zh` are covered.** On an `ar` / `de` / `es` / `fr` / `ja` / + `ko` / `pt` / `ru` console, `engine.*` strings render English. That is the + price of the carve-out, not a backfill someone forgot. +- **The i18n gates cannot see this namespace, by construction.** Key parity + ([`src/__tests__/all-locales-key-parity.test.ts`](./src/__tests__/all-locales-key-parity.test.ts)) + compares pack against pack, and `engine.*` is in no pack — so it is not an + *exception* to that test, it is outside its subject. The call-site gate + ([`scripts/check-i18n-call-site-keys.mjs`](../../scripts/check-i18n-call-site-keys.mjs)) + skips these call sites **by declaration**: the module is registered in its + `EXCLUDED_TRANSLATORS` list with a reason, and an imported `t` from any + unregistered module is a hard error there — so a second local table cannot + appear silently, and this carve-out cannot quietly widen. + +**When to revisit.** Migrating the namespace into the packs is mechanical but +wide (~1,300 keys × 8 further locales) and argues against the server-driven +design above, so it is not worth doing speculatively. The condition to reopen it +is concrete: a stated demand for an admin console in a language other than `en` +or `zh` — not a general wish for broader locale coverage, which the packs +already serve on every other surface. See objectui#4662 for the measurement and +the ruling. + ## Links - 📦 [npm package](https://www.npmjs.com/package/@object-ui/i18n)