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
{{ message }}
Repository navigation
showcase: eight authored validation messages on showcase_account / showcase_task are not on the translation channel, so they refuse in English on a zh-CN session #14518
showcase_account and showcase_task declare seven and one author-written validations[].message respectively, and none of them is on the #14253 translation
channel. On a zh-CN session those refusals arrive in English while the platform's own
built-in refusals (which have shipped zh-CN since #3957) arrive in Chinese — two
languages inside one error envelope.
This is the same defect #14311 fixed for showcase_project. That card's scope was the
New Project wizard, so only showcase_project's four rules were put on the channel
(PR #14517). The remaining eight were found while doing it and are recorded here rather
than widened into that PR.
Where
Untranslated authored rule messages, none of which has a objects.OBJECT._validations.RULE.message entry in examples/app-showcase/src/system/translations/index.ts:
examples/app-showcase/src/data/objects/account.object.ts — account_lifecycle, tax_id_format, billing_email_format, support_config_shape, churn_reason_consistency and its two nested conditional branches
(churn_reason_present, churn_reason_absent).
examples/app-crm has no _validations block at all, so every authored message in that
app is in the same position; whether the CRM demo is meant to be localised at all is a
separate question and is not assumed here.
Note that a nested conditional branch carries its own name and is addressed by that
name — the wrapping rule's message never reaches a user — so the two churn_reason_*
branches each need their own entry.
Why it is worth doing
The showcase is the app people read to learn what a correct ObjectStack app looks like.
An authored message with no bundle entry is the one way a refusal escapes the caller's
language, and the channel to fix it already exists and is already demonstrated on showcase_project.
Suggested shape
Mirror what PR #14517 did for showcase_project: add en + zh-CN_validations
entries for each rule, and extend the pin in examples/app-showcase/test/new-project-wizard-initial-status.test.ts (which today
asserts the invariant for showcase_project's whole rule set) to cover these objects
too — or lift it into a bundle-wide check so a newly declared rule without a translation
fails rather than rots.
The channel is real and the control fires: packages/spec/src/system/i18n-resolver.ts:1863 returns `objects.${objectName}._validations.${ruleName}.message` (#14253), read by packages/objectql/src/validation/rule-validator.ts:396,2168.
Correction — the population today is twelve, not eight
git grep -rn "_validations" origin/main -- examples/app-showcase/ returns zero matches. Nothing in the showcase is on that channel yet.
PR #14517 has not landed — it is open, draft, head 120d1d066, base a40c0f966. So showcase_project's four rules (end_after_start, spent_within_budget, project_status_flow, project_health_progression) are in the same position on main today as the eight you listed.
That does not weaken the card — your eight are genuinely additional, and filing them separately rather than widening #14517 was right. But it changes two things for whoever picks this up:
Add en + zh-CN_validations entries for every authored rule message on showcase_account and showcase_task, including a separate entry for each nested conditional branch — your note that a branch carries its own name and is addressed by it, while the wrapping rule's message never reaches a user, is the detail most likely to be missed, and it is correct.
Prefer your second option for the pin: a bundle-wide check rather than extending the per-object one. There is already a lint rule in this area (packages/lint/src/validate-translation-references.ts) — establish whether it can carry "an authored validations[].message with no bundle entry" before writing a bespoke test. A per-object pin extended twice is on its way to being extended a third time, and this card exists because the first extension stopped at one object.
Out of scope, as you framed it:examples/app-crm. You are right not to assume the CRM demo is meant to be localised at all — that is a separate question and it should not be answered by a translation PR. If someone wants it, separate card.
Routing
domain:engine — examples/* anchors to the subsystem it exercises (lane table), and the subsystem here is validation-rule message resolution (rule-validator.ts + the spec's i18n resolver). i18n, documentation.
priority:p3: example-app content, no customer-facing runtime defect, and the channel already exists so nothing is blocked. It is a real card rather than nothing because the showcase is what people read to learn a correct app, and a mixed-language error envelope teaches the wrong thing — your argument, and it holds. pm:queue.
Activity
huangyiirene commentedon Sep 2, 2026
Triage — graded. Confirmed at
origin/main4a37870, with one correction to the count.Confirmed
All eight rule names are where you say they are:
examples/app-showcase/src/data/objects/account.object.ts—:121account_lifecycle,:138tax_id_format,:150billing_email_format,:162support_config_shape,:184churn_reason_consistencywith:191churn_reason_presentand:199churn_reason_absent.examples/app-showcase/src/data/objects/task.object.ts:102—task_status_flow.The channel is real and the control fires:
packages/spec/src/system/i18n-resolver.ts:1863returns`objects.${objectName}._validations.${ruleName}.message`(#14253), read bypackages/objectql/src/validation/rule-validator.ts:396,2168.Correction — the population today is twelve, not eight
git grep -rn "_validations" origin/main -- examples/app-showcase/returns zero matches. Nothing in the showcase is on that channel yet.PR #14517 has not landed — it is open, draft, head
120d1d066, basea40c0f966. Soshowcase_project's four rules (end_after_start,spent_within_budget,project_status_flow,project_health_progression) are in the same position onmaintoday as the eight you listed.That does not weaken the card — your eight are genuinely additional, and filing them separately rather than widening #14517 was right. But it changes two things for whoever picks this up:
Scope ruled
Add
en+zh-CN_validationsentries for every authored rule message onshowcase_accountandshowcase_task, including a separate entry for each nestedconditionalbranch — your note that a branch carries its ownnameand is addressed by it, while the wrapping rule's message never reaches a user, is the detail most likely to be missed, and it is correct.Prefer your second option for the pin: a bundle-wide check rather than extending the per-object one. There is already a lint rule in this area (
packages/lint/src/validate-translation-references.ts) — establish whether it can carry "an authoredvalidations[].messagewith no bundle entry" before writing a bespoke test. A per-object pin extended twice is on its way to being extended a third time, and this card exists because the first extension stopped at one object.Out of scope, as you framed it:
examples/app-crm. You are right not to assume the CRM demo is meant to be localised at all — that is a separate question and it should not be answered by a translation PR. If someone wants it, separate card.Routing
domain:engine—examples/*anchors to the subsystem it exercises (lane table), and the subsystem here is validation-rule message resolution (rule-validator.ts+ the spec's i18n resolver).i18n,documentation.priority:p3: example-app content, no customer-facing runtime defect, and the channel already exists so nothing is blocked. It is a real card rather than nothing because the showcase is what people read to learn a correct app, and a mixed-language error envelope teaches the wrong thing — your argument, and it holds.pm:queue.Generated by Claude Code