Correction (rewritten). The original text of this issue claimed platform-objects declares 55 inline action labels with "no objects translation bundle at all". That was wrong. I grepped src/metadata-translations/ — which only re-exports the metadata-form baseline — and missed src/apps/translations/*.objects.generated.ts, where the object bundles actually live. All 55 inline action labels are translated in zh-CN / ja-JP / es-ES; os i18n check reports 0 action issues for the package. The wrong claim was also cited in #3753's body and in #3768's commit message as "the first installment" — treat those references as pointing at the corrected scope below. Apologies for the noise.
The real gap
Measured with os i18n check <extract config> --json against every package that has one, counting only user-authored surfaces (the platform metadata-form baseline is excluded — platform-objects owns and ships that):
| package |
missing per locale |
breakdown |
platform-objects |
77 |
navigation 49, widget 20, app 6, dashboard 2 |
plugin-security |
45 |
field 31, action 11, view 3 |
plugin-webhooks |
15 |
option 11, field 4 |
plugin-audit |
8 |
field 6, view 2 |
service-storage |
7 |
field 7 |
plugin-sharing |
7 |
field 4, option 3 |
plugin-approvals |
0 |
— |
service-messaging |
0 |
— |
service-realtime |
0 |
— |
| total |
159 |
× 3 locales (zh-CN / ja-JP / es-ES) = 477 strings |
Most of this was invisible before #3753, which taught the coverage detector to walk the whole declared surface rather than its own narrower copy.
Two distinct problems, which want different fixes
1. The objects-subtree gaps are a plain fill — plugin-security (45), plugin-webhooks (15), plugin-audit (8), plugin-sharing (7), service-storage (7). These keys live under objects.*, so os i18n extract already scaffolds them; the bundles just have not been regenerated and filled. Four of these packages' bundles are in fact already out of date against the schema (--check fails on plugin-security, plugin-audit, plugin-sharing, plugin-webhooks), so this is regenerate-then-translate.
2. platform-objects' 77 cannot be scaffolded at all today. They are apps.* / dashboards.* navigation and widget labels, which live outside the objects subtree — and the package extracts with --objects-only, so a fresh extract never writes them. That is why --check reports the package in sync while coverage reports 77 missing per locale: extract and coverage disagree about whether those keys are even in scope for this bundle. Needs a decision before any translating: emit the full TranslationData (drop --objects-only), or add a companion <locale>.apps.generated.ts next to the objects and metadata-forms bundles.
Also worth doing
Only platform-objects is wired into a CI check (pnpm check:i18n). The other eight packages have an i18n-extract.config.ts that nothing runs, which is how four of them drifted unnoticed. The #3768 ratchet covers examples/* only. Extending both gates to all nine configs is what stops this recurring — tracked as part of the work here.
Vocabulary check first
Before translating platform-objects' navigation labels into three languages, it is worth a pass on the source strings themselves — locking wording across four locales makes it markedly more expensive to change later.
Refs: #3370 (the gate), #3753 (walker unification + server-side inline-action translation), #3768 (examples ratchet).
The real gap
Measured with
os i18n check <extract config> --jsonagainst every package that has one, counting only user-authored surfaces (the platform metadata-form baseline is excluded —platform-objectsowns and ships that):platform-objectsplugin-securityplugin-webhooksplugin-auditservice-storageplugin-sharingplugin-approvalsservice-messagingservice-realtimeMost of this was invisible before #3753, which taught the coverage detector to walk the whole declared surface rather than its own narrower copy.
Two distinct problems, which want different fixes
1. The objects-subtree gaps are a plain fill —
plugin-security(45),plugin-webhooks(15),plugin-audit(8),plugin-sharing(7),service-storage(7). These keys live underobjects.*, soos i18n extractalready scaffolds them; the bundles just have not been regenerated and filled. Four of these packages' bundles are in fact already out of date against the schema (--checkfails onplugin-security,plugin-audit,plugin-sharing,plugin-webhooks), so this is regenerate-then-translate.2.
platform-objects' 77 cannot be scaffolded at all today. They areapps.*/dashboards.*navigation and widget labels, which live outside theobjectssubtree — and the package extracts with--objects-only, so a fresh extract never writes them. That is why--checkreports the package in sync while coverage reports 77 missing per locale: extract and coverage disagree about whether those keys are even in scope for this bundle. Needs a decision before any translating: emit the fullTranslationData(drop--objects-only), or add a companion<locale>.apps.generated.tsnext to the objects and metadata-forms bundles.Also worth doing
Only
platform-objectsis wired into a CI check (pnpm check:i18n). The other eight packages have ani18n-extract.config.tsthat nothing runs, which is how four of them drifted unnoticed. The#3768ratchet coversexamples/*only. Extending both gates to all nine configs is what stops this recurring — tracked as part of the work here.Vocabulary check first
Before translating
platform-objects' navigation labels into three languages, it is worth a pass on the source strings themselves — locking wording across four locales makes it markedly more expensive to change later.Refs: #3370 (the gate), #3753 (walker unification + server-side inline-action translation), #3768 (examples ratchet).