fix(i18n): promote framed send_failed out of the designTweak namespace (#4240) - #4251
Conversation
#4240) The refused-send error rows planned for core chrome frame the server reason with apps.designTweak.status.send_failed because it was the only framed variant in the catalog. That makes core depend on an app's catalog namespace: an app-side string edit could silently reword core error rows. Move the entry to pages.chatPage.send_failed_with_error (a sibling of the existing unframed pages.chatPage.send_failed) across all 12 hand-authored locale catalogs, regenerate en-XA, repoint designTweak's three call sites and its test, and delete the app-namespace entry. String values are byte-identical in every locale: this is a namespace move, not a wording change. A drift-guard test asserts the shared key exists framed in every runtime catalog and that no source file references the retired app key. Closes #4240
GPT 5.6 Review — ✅ no blocking findingsGPT 5.6 completed its review of This comment is updated in place on each push. Review detailsNo findings. False positive or not applicable? A repository writer can comment: |
UX Review (Fable 5) — ✅ PASSAdvisory UX-level review of This PR is purely an i18n key relocation — the string "Send failed: {{error}}" moves from the app-specific UX-Verdict: PASS Pure key relocation — every locale string is byte-identical, so no user sees anything different. [UX-REVIEWED] 0530644 |
Design Review (Fable 5) — ✅ PASSAdvisory design-level review of Design review complete. The diff is a namespace move (app → core catalog) with byte-identical values across all 12 locales, a new drift-guard test, and repointed call sites; I checked the catalog structure (no Design-Verdict: PASS Root-cause fix at the right ownership boundary: core-owned key, sibling not reuse, all locales moved atomically, dependent-PR handoff gated rather than hoped. [DESIGN-REVIEWED] 0530644 |
Opus 4.8 Review — ✅ no blocking findingsReviewed Verdict parsed from the review's SHA-scoped output markers for commit False positive or not applicable? A repository writer can comment: |
First Principles Review (Fable 5) — 🟡 CONCERNSAdvisory premise-level review of First-Principles-Verdict: CONCERNS The key move is a cause-level fix with a recorded decision behind it; the 85-line guard test mostly re-tests three gates that already exist. What this change shipsIntent: keep core chat error text out of an app-owned catalog namespace before #4214 makes core depend on it — a FIX.
Watch
Subtractions
[FIRST-PRINCIPLES-REVIEWED] 0530644 |
|
Disposition for the First Principles CONCERNS (advisory, head 0530644): Finding: tests 1 and 3 of Disposition: rebutted-in-part (proportionality), accepted-and-deferred-in-part.
|
bolichen97
left a comment
There was a problem hiding this comment.
Tier 1 auto-approve: cosmetic-UI/i18n (16 files). Criteria: no conflict, no requested changes, security path denylist clean, design-doc gate clean, SAST annotations clean, security checklist all-NO, AI reviewers green. Category: i18n key promotion from design-tweak namespace to shared namespace.
kirodotdev#4240) (kirodotdev#4251) The refused-send error rows planned for core chrome frame the server reason with apps.designTweak.status.send_failed because it was the only framed variant in the catalog. That makes core depend on an app's catalog namespace: an app-side string edit could silently reword core error rows. Move the entry to pages.chatPage.send_failed_with_error (a sibling of the existing unframed pages.chatPage.send_failed) across all 12 hand-authored locale catalogs, regenerate en-XA, repoint designTweak's three call sites and its test, and delete the app-namespace entry. String values are byte-identical in every locale: this is a namespace move, not a wording change. A drift-guard test asserts the shared key exists framed in every runtime catalog and that no source file references the retired app key. Closes kirodotdev#4240
Problem / Motivation
The framed send-failure string
"Send failed: {{error}}"lives atapps.designTweak.status.send_failed-- an APP's catalog namespace. Design Review flagged on PR #4214 that core chrome (the refused-send error rows planned for #4198) frames the server reason with that key because it is the only framed variant in the catalog. Core UI text would then be owned by an app's catalog subtree.Why it matters
An app-side string edit (rewording designTweak's send-failure status) would silently reword core chat error rows in all 12 languages -- with no test, gate, or reviewer signal connecting the two surfaces. Namespace ownership is the boundary that prevents that class of silent cross-surface drift.
What changed (motivation -> approach -> change)
Symptom: core call sites must reference an
apps.designTweak.*key to get a framed send-failure string. Root cause: the framed variant was only ever added to the app namespace. Fix: promote the entry to the shared namespace the issue proposes (pages.chatPage).pages.chatPage.send_failedalready exists (unframed"Send failed", live inChatPage.tsxwith a no-parameter call), so the framed variant lands as a sibling:pages.chatPage.send_failed_with_error. Reusing the existing key would have changed ChatPage's rendered text ("One key, one meaning" perwebsite/docs/i18n-catalog.md).en.manual.json+ 11 translations) -- values byte-identical in every locale; this is a namespace move, not a wording change. Regenerateden-XAviascripts/gen-pseudolocale.mjs.DesignTweakPage.tsx) and its test to the shared key, and deleted the app-namespace entry (designTweak no longer uses it, and a dangling duplicate would rot).Coordination note: open PR #4214 references the old key from its new call sites (App.tsx, useSceneInteraction.tsx). Once this merges, its rebase repoints them to
pages.chatPage.send_failed_with_error-- its owncheck-i18n-keyshard-zero gate makes that unmissable rather than silent.Tests
website/src/i18n/sendFailedSharedKey.test.ts(mutation-verified in both directions):pages.chatPage.send_failed_with_errorwith the{{error}}placeholder intact (a missing key would render the raw key string as UI text);apps.designTweak.status.send_failed;DesignTweakRequestsCov80.test.tsxasserts the send-failure status renders from the shared key.Manual verification
N/A -- unit coverage sufficient: the change is a catalog key move with byte-identical values, locked by the parity/i18n gate chain (
i18n:checkgreen: pseudolocale, key-refs hard-zero, DNT, parity) plus the new drift-guard test.Screenshots / video
Why no screenshot: pure i18n key rename with byte-identical string values in every locale -- no pixel changes.
Related Issues
Closes #4240
Checklist
feat|fix|docs|refactor|perf|test|chore|ci|build|revert: ...)