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
Protected main@193a87ef54c3fe6dcda4755bce4d6bc81e3a0297 does not satisfy the LifeOS product locale contract.
Current Web localization is browser/static-catalog authority:
apps/web/app/localization.ts defines SupportedLocale = 'en' | 'ko' and imports only static en.json / ko.json catalogs;
apps/web/messages/ contains only those two locale files;
localization.test.ts proves structural parity only between Korean and English and falls unsupported fr / ja preferences back to English;
Today stores the selected locale only in browser localStorage under life-os.locale.v1 and derives fallback from navigator.languages.
This is useful bootstrap behavior, but it cannot provide durable cross-device locale preference, KO/EN/JA/ZH/VI/ES/DE/FR resource parity, reviewed resource versions, deterministic cache invalidation, or buyer-verifiable screen-key provenance.
Required outcome
LifeOS must support KO/EN/JA/ZH/VI/ES/DE/FR through a server-backed, versioned translation resource ledger and a bounded screen-key cache. A returning user on another device receives the durable locale preference and an exact resource version without the browser becoming the persistence owner.
The translation ledger is separate from the ontology-label ledger. It is not a requirement to preload a full browser catalog or build a monolithic translation SPA. Browser bundles/cache entries may remain screen-scoped and lazy as long as version/provenance and fallback semantics are explicit.
DDD ownership decision before production implementation
Do not place a new translation database behind Web merely because Web renders strings, and do not place arbitrary translation-resource truth in Identity merely because Identity can own user preference.
The first implementation PR must carry a Proposed ADR/Context Map choosing one canonical owner for translation resources. The preferred decomposition to evaluate is:
Identity / Account Settings owns only durable user locale preference and the authenticated preference mutation/read contract;
a Localization supporting bounded context owns translation resource versions, locale/screen/message-key values, review/publication state, resource digests and cache-version evidence;
Web consumes released/versioned localization contracts through its server boundary and keeps only bounded screen-key cache/materialized browser-safe resources;
ontology/concept labels remain outside this ledger and are consumed through their own semantic owner contract.
If an existing service is selected instead of a new Localization bounded context, the ADR must show why its ubiquitous language, aggregate ownership, persistence lifecycle and service credentials are actually compatible. Convenience co-location is not sufficient.
Minimum domain model
The canonical contract must make these concepts explicit and map them to API/DB/test artifacts:
LocaleCode — allowlisted canonical locale identity for ko, en, ja, zh, vi, es, de, fr;
ScreenKey and MessageKey — stable product/UI identities, not translated text and not ontology identifiers;
TranslationResourceVersion — immutable published version identity with creation/publication evidence;
TranslationResourceDigest — deterministic digest over the exact published resource set;
explicit publication invariant: a version cannot be treated as complete for a declared screen until all required locale/key pairs are present and reviewed;
explicit fallback invariant: missing/invalid resources fail visibly or follow a documented deterministic fallback; they are never silently mistaken for complete localization.
Use service-owned PostgreSQL persistence/migrations/credentials, 3NF naming, bounded queries, deterministic ordering and idempotent publication. No cross-service SQL or source copy.
Locale-preference boundary
Durable locale preference is account/user evidence, not browser authority.
authenticated server authority determines the user/workspace context;
browser input may request one allowlisted locale but cannot nominate user/workspace identity;
anonymous/local preference may remain local until explicit authenticated attachment/consent;
malformed/case/whitespace aliases must follow an explicit request-normalization contract and durable stored evidence must already be canonical;
locale preference and translation resource version are separate identities and may evolve independently.
Screen-key cache contract
The browser/server cache must be bounded by at least locale + screen + exact published resource version/digest. A stale cache from version N must not be treated as version N+1 after publication.
Required states include cold miss, warm hit, version rollover, missing key, resource unavailable, permission/error path and recovery. Do not hide resource failures by shipping an untracked hard-coded English string on a screen declared complete.
RED acceptance
Start with realistic regression evidence against protected behavior, not production implementation. At minimum prove that current protected source cannot satisfy:
ja, zh, vi, es, de, fr as first-class supported locale contracts;
durable cross-device locale preference without relying on localStorage;
exact resource-version binding for a screen cache;
eight-locale screen-key completeness/publication;
deterministic stale-cache invalidation after a new resource version;
translation-ledger / ontology-label separation.
Do not make the first RED a synthetic in-memory-only replacement for required persistence behavior. Unit fixtures may be synthetic, but PostgreSQL and buyer-path evidence must use the real migrations/adapters once production persistence exists.
GREEN acceptance
KO/EN/JA/ZH/VI/ES/DE/FR are valid canonical product locales with published resource evidence.
Account locale preference is durable, authenticated and recoverable across devices.
Translation resources are DB-versioned and immutable once published; supersession creates a new version rather than mutating historical evidence.
Every declared complete screen has locale/key parity for the exact published version.
Web fetch/cache is screen-scoped and exact-version-bound; stale versions cannot masquerade as current.
Missing/unavailable resources are explicit states, never silent success.
CJK font fallback, text expansion, truncation/overflow, keyboard/focus/accessibility labels and responsive layouts are exercised per material screen.
Storybook/E2E covers normal/loading/empty/error/permission/offline/cache-rollover states where applicable and references the relevant Figma node/token authority.
Owned production statement/branch/function/line coverage, edge cases and production docstrings remain at repository-enforced targets.
If a buyer-path API is introduced, current-head async/k6 evidence measures the intended p95 ≤ 20 ms contract without warm-cache/sample exclusions.
Existing KO/EN static catalogs are source data to migrate/reconcile, not an excuse to maintain two mutable translation authorities indefinitely. The migration plan must define bootstrap/import, digest comparison, rollback, version history and when static fallback ceases to be canonical. A temporary compatibility adapter must have an ADR removal condition.
Non-goals
translating ontology/concept labels inside the UI translation ledger;
browser-owned durable locale/resource truth;
a full-catalog SPA download as a prerequisite for every route;
machine-generated translations being auto-published without explicit publication/review evidence;
hard-coded English fallback being counted as eight-locale completion;
moving unrelated user/profile persistence into a localization service.
Integration order
Keep #209 as the buyer-journey umbrella and #211 as the only docs/product-technical-gap-baseline.md writer. This issue owns the localization gap and owner-boundary decision. The first code PR should be regression/ADR-first from fresh protected main and remain Draft until its owner contract is explicit; material workspace PRs may continue independently but must not claim localization completion from KO/EN static catalogs.
Buyer-visible failure
Protected
main@193a87ef54c3fe6dcda4755bce4d6bc81e3a0297does not satisfy the LifeOS product locale contract.Current Web localization is browser/static-catalog authority:
apps/web/app/localization.tsdefinesSupportedLocale = 'en' | 'ko'and imports only staticen.json/ko.jsoncatalogs;apps/web/messages/contains only those two locale files;localization.test.tsproves structural parity only between Korean and English and falls unsupportedfr/japreferences back to English;localStorageunderlife-os.locale.v1and derives fallback fromnavigator.languages.This is useful bootstrap behavior, but it cannot provide durable cross-device locale preference, KO/EN/JA/ZH/VI/ES/DE/FR resource parity, reviewed resource versions, deterministic cache invalidation, or buyer-verifiable screen-key provenance.
Required outcome
LifeOS must support KO/EN/JA/ZH/VI/ES/DE/FR through a server-backed, versioned translation resource ledger and a bounded screen-key cache. A returning user on another device receives the durable locale preference and an exact resource version without the browser becoming the persistence owner.
The translation ledger is separate from the ontology-label ledger. It is not a requirement to preload a full browser catalog or build a monolithic translation SPA. Browser bundles/cache entries may remain screen-scoped and lazy as long as version/provenance and fallback semantics are explicit.
DDD ownership decision before production implementation
Do not place a new translation database behind Web merely because Web renders strings, and do not place arbitrary translation-resource truth in Identity merely because Identity can own user preference.
The first implementation PR must carry a Proposed ADR/Context Map choosing one canonical owner for translation resources. The preferred decomposition to evaluate is:
If an existing service is selected instead of a new Localization bounded context, the ADR must show why its ubiquitous language, aggregate ownership, persistence lifecycle and service credentials are actually compatible. Convenience co-location is not sufficient.
Minimum domain model
The canonical contract must make these concepts explicit and map them to API/DB/test artifacts:
LocaleCode— allowlisted canonical locale identity forko,en,ja,zh,vi,es,de,fr;ScreenKeyandMessageKey— stable product/UI identities, not translated text and not ontology identifiers;TranslationResourceVersion— immutable published version identity with creation/publication evidence;TranslationEntry— locale + screen key + message key + value + review/publication state;TranslationResourceDigest— deterministic digest over the exact published resource set;Use service-owned PostgreSQL persistence/migrations/credentials, 3NF naming, bounded queries, deterministic ordering and idempotent publication. No cross-service SQL or source copy.
Locale-preference boundary
Durable locale preference is account/user evidence, not browser authority.
Screen-key cache contract
The browser/server cache must be bounded by at least locale + screen + exact published resource version/digest. A stale cache from version N must not be treated as version N+1 after publication.
Required states include cold miss, warm hit, version rollover, missing key, resource unavailable, permission/error path and recovery. Do not hide resource failures by shipping an untracked hard-coded English string on a screen declared complete.
RED acceptance
Start with realistic regression evidence against protected behavior, not production implementation. At minimum prove that current protected source cannot satisfy:
ja,zh,vi,es,de,fras first-class supported locale contracts;localStorage;Do not make the first RED a synthetic in-memory-only replacement for required persistence behavior. Unit fixtures may be synthetic, but PostgreSQL and buyer-path evidence must use the real migrations/adapters once production persistence exists.
GREEN acceptance
Migration compatibility
Existing KO/EN static catalogs are source data to migrate/reconcile, not an excuse to maintain two mutable translation authorities indefinitely. The migration plan must define bootstrap/import, digest comparison, rollback, version history and when static fallback ceases to be canonical. A temporary compatibility adapter must have an ADR removal condition.
Non-goals
Integration order
Keep #209 as the buyer-journey umbrella and #211 as the only
docs/product-technical-gap-baseline.mdwriter. This issue owns the localization gap and owner-boundary decision. The first code PR should be regression/ADR-first from fresh protected main and remain Draft until its owner contract is explicit; material workspace PRs may continue independently but must not claim localization completion from KO/EN static catalogs.Refs #209 #211.