Text and Help conventions
Look up internationalization, product text, and Help rules with their canonical owners and checks.
7 min read
Updated 2026-10-16
#conventions#i18n#text#help
Use these rows with the Conventions for Cloud applications index and audit procedure. Follow each canonical link for the complete contract.
Internationalization (I18N)
| ID | Rule | Why | How to check | Canonical |
|---|---|---|---|---|
| I18N-01 | Own human-facing strings beside the code or content that writes them, using i18n.define() for messages. |
Message ownership stays readable without speculative shared catalogs. | bun scripts/check.ts localization checks monorepo shipped EN/DE catalogs and hard-coded prose in catalog-only frontends, currently Mail; Manual: read message definitions beside each feature and inspect UI text for strings outside its catalog. |
String ownership |
| I18N-02 | Resolve messages once at each runtime boundary from the request or inherited UI locale, with no process-global locale or ordinary component locale props. | Concurrent SSR requests remain isolated and islands use the server's locale. | Manual: trace getLocale(c) and useLocale() through SSR and islands; inspect module state and component props, then apply the internationalization review checklist. |
Runtime boundaries |
| I18N-03 | Keep the complete base application presentation in its declaration and use presentation for localized overlays without changing IDs, routes, or permissions. |
Every request-scoped surface receives the same application presentation. | Manual: read defineApp() presentation overlays and compare navigation, administration, and Help in each shipped locale. |
Application presentation |
| I18N-04 | Translate at least the title and description of every capability Type, Query, Action, Command, and search tag when shipping another language. | Assistant, approvals, search, and the catalog show application-owned presentation. | bun scripts/check.ts capability-presentation covers built-in capability declarations only; Manual: compare each capability's base and translated titles and descriptions, then inspect the catalog in that locale. |
Capability presentation |
| I18N-05 | Format semantic numbers and time at the rendering owner with the inherited or explicit request locale, keeping timezone separate from language. | Runtime defaults do not make SSR and browser output disagree. | Manual: use rg 'toLocaleString|toLocaleDateString|Intl.DateTimeFormat' src and inspect each display seam for an explicit locale or shared formatter. |
Value formatting |
| I18N-06 | Keep codes, statuses, structured details, and operational logs locale-independent while the owning layer localizes human messages. | Clients can branch on stable codes and people can read the failure and recovery. | Manual: compare one failed operation in two locales; inspect client branches for code comparisons rather than translated text. | Human and machine messages |
| I18N-07 | Carry locale across application boundaries as metadata and return final display strings rather than message keys. | Consumers need no provider dictionary, and delayed work uses its intended locale. | Manual: trace locale through each capability, widget, job, and notification; inspect payloads for message keys and notification locale fields that belong in metadata. | Cross-application boundaries |
| I18N-08 | Test base and translated output, regional and per-key fallback, concurrent SSR isolation, initial browser agreement, formatting, stable codes, and any locale transport the feature uses. | Locale behavior is verified at the boundary that owns it. | Manual: read locale tests for these cases and compare Intl expectations with the runtime formatter for the requested locale. |
Locale tests |
| I18N-09 | Keep English and German equivalent in facts, state, scope, permissions, uncertainty, and recovery, using idiomatic wording. | A translation does not change the product's meaning. | bun scripts/check.ts localization checks monorepo shipped EN/DE key completeness, not meaning; Manual: compare both versions in context for the same facts and consequences. |
Equivalent languages |
| I18N-10 | Write complete translatable thoughts with semantic arguments instead of concatenated fragments or transformations of resolved text. | Each locale controls grammar, case, and agreement. | Manual: use rg 'Before|After|Prefix|Suffix|toLowerCase|toUpperCase' src and inspect message composition, including assistive text. |
Translation-safe messages |
| I18N-11 | Built-in apps: word every app in Cloud's Assistant and chat presentation through its own presentation, without branches on app IDs, names, or tool names. | Built-in and third-party apps read the same. | bun scripts/check.ts app-neutral-assistant; Manual: read Assistant and chat presentation code, capability-sentences, and tool-sentences for app identity comparisons or lookups that select wording. |
App-neutral presentation |
Product text and Help (DOC)
| ID | Rule | Why | How to check | Canonical |
|---|---|---|---|---|
| DOC-01 | Write in one calm, direct, precise, respectful, and restrained product voice, adding text only when it helps a person decide, recover, or understand a consequence. | Product text names the real state and next action without blame or filler. | Manual: read controls, feedback, and Help in context against the product voice table. | Product voice |
| DOC-02 | Write short, sentence-case controls that name the action, destination, value, or current state, with localized names for icon-only actions. | Controls remain clear without surrounding prose. | Manual: inspect buttons, navigation, fields, statuses, and accessible names; replace vague action labels when the concrete action is known. | Short controls |
| DOC-03 | Use labels for field meaning, input examples for format, hints for constraints or consequences, and tooltips only for supplementary information. | Essential guidance stays visible where the person needs it. | Manual: read each field label, example, hint, and tooltip; verify the task is possible without opening a tooltip. | One-sentence guidance |
| DOC-04 | Explain the actual state and outcome with the known fact and safe recovery, and claim irreversible success only after server confirmation. | Failed content does not look empty, and feedback does not promise an unconfirmed outcome. | Manual: trigger loading, empty, validation, failed-read, and saved-but-refresh-failed states; compare the wording with the state table. | States and outcomes |
| DOC-05 | Name the action and object in a confirmation title, its concrete consequence in the body, and the action again on the confirmation button. | The person understands the scope and irreversibility before agreeing. | Manual: open each destructive confirmation with demo data and compare its title, body, button, and recovery claim with the action. | Confirmation text |
| DOC-06 | Lead compact notifications with the domain change, add only needed context, and link to the relevant authorized destination without repeating the title or exposing sensitive details. | The person can assess the event without sensitive content in the notification. | Manual: inspect notification title, body, and destination with demo data; check that urgency reflects a real deadline or risk. | Compact messages |
| DOC-07 | Keep file-backed Help in src/help/index.ts with its Markdown below src/help/, explicitly importing every article into one declaration. |
Content ownership and bundle contents remain visible without filesystem scanning. | Manual: inspect the Help module and article imports; use src/help.ts only when it owns no Markdown files. |
Help module |
| DOC-08 | Register Help through app.start() rather than adding another Help API router, registrar, or standalone Help routes. |
The platform's readers consume one published declaration. | Manual: trace the Help declaration to app.start({ help }) and inspect route and layout wiring for duplicate registration. |
Help registration |
| DOC-09 | Write Help with one action per numbered step sentence, short active sentences, warnings before their steps, exact labels, clear verbs, and no filler or long noun stacks. | People and agents can scan the next action in either language. | bun scripts/check.ts help-writing checks built-in step length and glossary synonyms against scripts/checks/help-writing.baseline; Manual: third-party apps apply the same writing rules and glossary, count step sentences at 20 words or fewer, and read articles for voice, order, and meaning. |
Help writing rules |
| DOC-10 | Use the glossary's English and German term for each product concept and avoid its listed synonyms, while quoting interface labels exactly. | UI text, Help, messages, and notifications use one term per meaning. | bun scripts/check.ts help-writing checks synonyms in built-in Help against its baseline, excluding code and bold labels; Manual: compare product terms with the glossary and preserve exact interface labels. |
Cloud glossary |
| DOC-11 | Built-in apps: document observable contract changes on the canonical owning page and update the matching examples or UI guidance. | Public sources describe the same behavior as the code. | Manual: compare the changed API, default, error, permission, UI, or operational behavior with the documentation ownership table. | Documentation ownership |
| DOC-12 | Built-in apps: update the published skill and its cases when the stable public workflow or a cross-cutting application invariant changes, keeping API detail in canonical guides. | Agent knowledge stays aligned without duplicating API documentation. | Manual: compare the change with cloud-dev and its evaluation cases; keep detailed API changes in their owning guide. |
Agent knowledge |