You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
i18n: two surfaces a translation bundle cannot address at all — walkAddressedPageComponents misses a slotted page's slots and a tabs node's items[].children, and dashboards.NAME has no globalFilters group #16772
Split off #16735 (findings 2 and 3) by the triage seat. They are one card because both are the same defect — a surface the console renders but a bundle has no key for — both live in packages/spec, and both would otherwise produce two PRs touching the same package.
Original provenance: filed from an app repo (objectstack-ai/hotclm, @objectstack/* 17.3.0) after translating it end to end into en + zh-CN — objectstack-ai/hotclm#32, PR objectstack-ai/hotclm#33. The reporter states they did not personally re-drive these; see Provenance and boundaries below.
Finding A — pages.NAME.components.* addresses nothing on a kind: 'slotted' page, and a tab label has no key on any page kind
against 21 authored components and tab labels (@objectstack/spec 17.3.0). walkAddressedPageComponents is the traversal translatePage itself runs, so this is unresolvable rather than merely ungated.
Two independent causes, either sufficient on its own:
its roots are regions[].components[], and a slotted page authors slots;
its descent is properties.children, and a page:tabs carries properties.items[].children.
⇒ pages.contract_detail carries exactly two addressable keys, label and description, while 7 tab labels, 7 path stages, 7 related-list titles and 1 block label cannot be reached from a bundle at all. Worked around in the app with 22 inline locale maps.
Triage's own reading, on origin/main — the roots half is confirmed from the signature and the first pass:
packages/spec/src/system/i18n-resolver.ts:1568 export function walkAddressedPageComponents(
:1569 doc: Pick<PageLike, 'regions'>,
:1578 if (Array.isArray(doc.regions)) {
:1579 for (const region of doc.regions) {
:1580 if (!region || typeof region !== 'object' || !Array.isArray(region.components)) continue;
⇒ the parameter type itself is Pick<PageLike, 'regions'> — a slotted page's slots is not merely skipped, it is outside the declared input. ⚠️ The properties.children descent half was not separately verified by triage; re-derive it.
Finding B — dashboards.NAME has no group for globalFilters
A dashboard's global-filter labels and their option labels are not addressable — and the filter bar draws directly above the widget titles the bundle does translate, so the mixed-language result is maximally visible:
类别: 全部 Requesting Department: 全部
[six Chinese widget titles below]
5 filter labels + 29 option labels in that app. Worked around with inline maps.
Triage's own reading, on origin/main — confirmed, the group has exactly four members:
⇒ label · description · actions · widgets. No globalFilters.
Why these two are Bug and not Feature
Both are the benign direction of the same seam#16735's finding 1 describes: there is nothing to address, so nothing claims coverage, so os i18n check does not lie about them. That is why they are p2 and not higher.
They are still Bug rather than Feature because the console already renders these strings and the platform already declares that a bundle is how you translate a page or a dashboard. A declared translation surface that cannot reach a rendered string is a contract not delivered, not a capability nobody promised.
Suggested shape (⛔ not a prescription)
A: widen the traversal's roots to include a slotted page's slots, and its descent to include properties.items[].children. ⚠️ The parameter type changes with it (Pick<PageLike, 'regions'> no longer describes the input), so this is a published-signature change in packages/spec — expect contract review.
B: add a globalFilters group to the dashboard translation schema, keyed the way widgets and actions already are, covering both the filter label and its option labels.
⛔ Do not collapse A and B into one traversal change; they are different files and different shapes and only share a lane.
Acceptance
A slotted page with tab labels yields a non-zero walkAddressedPageComponents count, and each authored key resolves.
A dashboard's global-filter labels and option labels are addressable from a bundle and render translated.
The 22 + 34 inline locale maps in the reporting app become removable (⛔ not this card's job to remove them — the app's).
⚠️ Triage verified the two code readings quoted above and nothing else — not the counts (21 components, 5 filter labels, 29 option labels), not the browser behaviour.
⛔ Dedup could not be run from the reporting session: search_issues returned total_count: 0 for the app's own repo even on a control term certainly present in an open issue's title, so the index was not answering. The run correctly reported this rather than filing blind. ⚠️ Whoever claims this should re-run the duplicate search.
One app, one console build, one dialect. Re-confirm before acting.
Split off #16735 (findings 2 and 3) by the triage seat. They are one card because both are the same defect — a surface the console renders but a bundle has no key for — both live in
packages/spec, and both would otherwise produce two PRs touching the same package.Original provenance: filed from an app repo (
objectstack-ai/hotclm,@objectstack/*17.3.0) after translating it end to end intoen+zh-CN—objectstack-ai/hotclm#32, PRobjectstack-ai/hotclm#33. The reporter states they did not personally re-drive these; see Provenance and boundaries below.Finding A —
pages.NAME.components.*addresses nothing on akind: 'slotted'page, and a tab label has no key on any page kindagainst 21 authored components and tab labels (
@objectstack/spec17.3.0).walkAddressedPageComponentsis the traversaltranslatePageitself runs, so this is unresolvable rather than merely ungated.Two independent causes, either sufficient on its own:
regions[].components[], and a slotted page authorsslots;properties.children, and apage:tabscarriesproperties.items[].children.⇒
pages.contract_detailcarries exactly two addressable keys,labelanddescription, while 7 tab labels, 7 path stages, 7 related-list titles and 1 block label cannot be reached from a bundle at all. Worked around in the app with 22 inline locale maps.Triage's own reading, on
origin/main— the roots half is confirmed from the signature and the first pass:⇒ the parameter type itself is⚠️ The
Pick<PageLike, 'regions'>— a slotted page'sslotsis not merely skipped, it is outside the declared input.properties.childrendescent half was not separately verified by triage; re-derive it.Finding B —
dashboards.NAMEhas no group forglobalFiltersA dashboard's global-filter labels and their option labels are not addressable — and the filter bar draws directly above the widget titles the bundle does translate, so the mixed-language result is maximally visible:
5 filter labels + 29 option labels in that app. Worked around with inline maps.
Triage's own reading, on
origin/main— confirmed, the group has exactly four members:⇒
label·description·actions·widgets. NoglobalFilters.Why these two are
Bugand notFeatureBoth are the benign direction of the same seam #16735's finding 1 describes: there is nothing to address, so nothing claims coverage, so
os i18n checkdoes not lie about them. That is why they arep2and not higher.They are still
Bugrather thanFeaturebecause the console already renders these strings and the platform already declares that a bundle is how you translate a page or a dashboard. A declared translation surface that cannot reach a rendered string is a contract not delivered, not a capability nobody promised.Suggested shape (⛔ not a prescription)
slots, and its descent to includeproperties.items[].children.Pick<PageLike, 'regions'>no longer describes the input), so this is a published-signature change inpackages/spec— expect contract review.globalFiltersgroup to the dashboard translation schema, keyed the waywidgetsandactionsalready are, covering both the filter label and its option labels.⛔ Do not collapse A and B into one traversal change; they are different files and different shapes and only share a lane.
Acceptance
walkAddressedPageComponentscount, and each authored key resolves.Provenance and boundaries
record:details: the #13855sections[].groupreference form crashes the renderer, and the enumeratedfieldsform renders raw field keys instead of declared labels #16695) — so this run's output is not offered as unexamined, but it is also not independently confirmed end to end.search_issuesreturnedtotal_count: 0for the app's own repo even on a control term certainly present in an open issue's title, so the index was not answering. The run correctly reported this rather than filing blind.Split siblings
_views.VIEW.descriptionis declared, walked and counted as covered but never rendered — plus three surfaces a bundle cannot address at all #16735 — finding 1,_views.VIEW.descriptiondeclared, walked, counted as covered, never rendered.repo:objectui. That is the one with a gate consequence; if only one of the family is picked up, it should be that one.selectfield's options render untranslated on a SAME-object dataset dimension, while the identical values translate on a dotted cross-object one #16773 — finding 4, chart category labels fromselectoptions ignore the bundle.domain:services.https://claude.ai/code/session_01SwJQDFKe8tVit3BXQ9EfR5