fix(i18n): resync ko Storage catalog with the inventory model - #2306
Conversation
The Storage screen moved from a bucket model to an inventory model. That key migration was applied to en.json and never to ko.json, so Korean carries 36 keys English no longer has and lacks the 29 it gained. Both halves of catalogParity fail, which reds Frontend Tests for every pull request touching website/. Delete the 36 retired bucket keys and translate the 29 inventory ones. Every removed key has zero call sites in website/src. Wording follows the terms already in ko.json rather than a dictionary: 세션 스토리지, 턴, 선택 해제, 오래된순, 회수, 휴지통으로 이동. trash_summary and trash_batch_reason recover their Korean from the retired batch_detail, which the redesign split into two keys. No English, no other locale and no code is touched. Fixes kirodotdev#2298
GPT 5.6 Review (fork) — ✅ no blocking findingsReviewed Review detailsNo findings. |
Opus 5 Review (fork) — ✅ no blocking findingsReviewed |
Design Review (Fable 5, fork) — ✅ PASSAdvisory design-level review of Design-Verdict: PASS Minimal catalog-only resync that exactly restores en↔ko key parity (verified: 7 survivors + 29 additions = en's 36-key set, placeholders intact); right scope, right layer. [DESIGN-REVIEWED] 462e9f3 |
UX Review (Fable 5, fork) — ✅ PASSAdvisory UX-level review of All strings verified against UX-Verdict: PASS Korean Storage strings are accurate, self-explanatory, and consistent with catalog precedent; the destructive-path copy now reaches Korean users in Korean. Suggestions
[UX-REVIEWED] 462e9f3 |
`**中文文本(带括号)。**这句子继续` renders as literal asterisks today. So does every Chinese, Japanese and Korean phrase whose emphasised run ends in ideographic punctuation — which, in CJK prose, is most of them. Root cause is a known CommonMark defect (commonmark/commonmark-spec#650), not our renderer. A closing `**` is only right-flanking when it is NOT preceded by punctuation, or IS followed by whitespace/punctuation. Here it is preceded by `。` and followed by the letter `这`, so it fails both clauses and cannot close. English sidesteps this by writing `**bold.** tail` with a space; CJK cannot, because the space is visibly wrong. Adopts the two upstream plugins that implement the CJK-friendly flanking amendment — the same pair Vercel's Streamdown ships as `@streamdown/cjk`: - `remark-cjk-friendly` runs BEFORE remark-gfm; it changes how emphasis delimiters are classified. - `remark-cjk-friendly-gfm-strikethrough` runs AFTER remark-gfm; it extends gfm's own `~~` construct. Order is load-bearing, so the tests assert rendered DOM rather than plugin presence: they fail if either plugin is dropped OR mis-ordered. Deliberately NOT adopted from the same upstream package: its autolink boundary handling. That splits a URL at the FIRST character in a fixed CJK punctuation set, unconditionally, which was measured to break real links — `…/wiki/苹果(公司)` becomes `…/wiki/苹果`, `…/wiki/モーニング娘。` becomes `…/wiki/モーニング娘`, `…/wiki/我,机器人` becomes `…/wiki/我`. It also cannot repair the code-span pairing that a swallowed backtick shifts, because it runs after tokenization. That problem is handled separately in #2171. Verified against the whole suite: 11356 pass. The one red, `catalogParity ko`, is pre-existing on main (ko.json is missing 101 `_one` plural keys as of #2306) and touches no file in this diff.
Squashed to one commit to satisfy the Enforce single commit hygiene gate; the per-pick provenance is preserved below. Each pick is patch-identical to the commit already merged on main (verified with git patch-id --stable). Requested for this RC: - feat: opt-in Slack setup and multi-channel repositioning (#2340) kirocrew setup no longer walks through Slack credentials unless --slack is passed, plus multi-channel repositioning across docs, in-app copy, and all 13 locales. (cherry picked from commit 8f5c937) - fix(i18n): drop shebangs that break test collection on Windows (#2378) (cherry picked from commit ab20b4e) Required to make this branch green, not optional additions: - fix(i18n): resync ko Storage catalog with the inventory model (#2306) release/0.2.0 already failed catalogParity > ko at 5fe4bd5 with 29 missing and 36 orphaned pages.sessionStorage.* keys. #2208 rewrote the English Storage keys on this branch while its Korean resync stayed on main, so Korean users saw raw key names on the Storage page and every PR touching website/ was red. (cherry picked from commit 841e8b4) - fix(i18n): match ko sort_largest spacing to the catalog convention (#2370) (cherry picked from commit 49aa776) Added here: - docs: note opt-in Slack setup in the 0.2.0 changelog. #2340 changes first-run behavior and the existing [0.2.0] section did not mention it. A feat on a cut release branch is a deliberate maintainer decision, not an oversight: CONTRIBUTING.md reserves a cut branch for bug fixes, and the multi-channel positioning was judged the accurate story to ship in 0.2.0.
…2395) Squashed to one commit to satisfy the Enforce single commit hygiene gate; the per-pick provenance is preserved below. Each pick is patch-identical to the commit already merged on main (verified with git patch-id --stable). Requested for this RC: - feat: opt-in Slack setup and multi-channel repositioning (#2340) kirocrew setup no longer walks through Slack credentials unless --slack is passed, plus multi-channel repositioning across docs, in-app copy, and all 13 locales. (cherry picked from commit 8f5c937) - fix(i18n): drop shebangs that break test collection on Windows (#2378) (cherry picked from commit ab20b4e) Required to make this branch green, not optional additions: - fix(i18n): resync ko Storage catalog with the inventory model (#2306) release/0.2.0 already failed catalogParity > ko at 5fe4bd5 with 29 missing and 36 orphaned pages.sessionStorage.* keys. #2208 rewrote the English Storage keys on this branch while its Korean resync stayed on main, so Korean users saw raw key names on the Storage page and every PR touching website/ was red. (cherry picked from commit 841e8b4) - fix(i18n): match ko sort_largest spacing to the catalog convention (#2370) (cherry picked from commit 49aa776) Added here: - docs: note opt-in Slack setup in the 0.2.0 changelog. #2340 changes first-run behavior and the existing [0.2.0] section did not mention it. A feat on a cut release branch is a deliberate maintainer decision, not an oversight: CONTRIBUTING.md reserves a cut branch for bug fixes, and the multi-channel positioning was judged the accurate story to ship in 0.2.0.
…tdev#2306) The Storage screen moved from a bucket model to an inventory model. That key migration was applied to en.json and never to ko.json, so Korean carries 36 keys English no longer has and lacks the 29 it gained. Both halves of catalogParity fail, which reds Frontend Tests for every pull request touching website/. Delete the 36 retired bucket keys and translate the 29 inventory ones. Every removed key has zero call sites in website/src. Wording follows the terms already in ko.json rather than a dictionary: 세션 스토리지, 턴, 선택 해제, 오래된순, 회수, 휴지통으로 이동. trash_summary and trash_batch_reason recover their Korean from the retired batch_detail, which the redesign split into two keys. No English, no other locale and no code is touched. Fixes kirodotdev#2298
Problem / Motivation
catalogParityis red onmain. The Korean catalog is desynced fromenacross thewhole Storage screen, so
Frontend Testsfails for every open pull request thattouches
website/:Reproduced on a pristine checkout of
main: 2 failed | 75 passed (77).Why it matters
Two layers, as #2298 sets out:
strings, including the destructive-action explanations (
cannot_delete_running,cannot_delete_resumable). Those are the strings you least want falling back to alanguage the user did not choose.
catalogParityruns insideFrontend Tests, so this reds an unrelatedPR's
Frontend Tests→Coverage Gate→PR Readinesschain. Every author iscurrently proving the failure is not theirs before they can call their own PR green.
What changed (motivation → approach → change)
Root cause. The two assertions are one event.
ko.jsonwas translated against thebucket-based Storage screen, and the inventory-model redesign replaced that key set in
en.jsonwithout re-syncing Korean. The 36 strays are the retired bucket vocabulary(
bucket_7_30d,threshold_90d,batch_detail, …); the 29 missing are the inventoryvocabulary
engained. It is the rename half of a key migration applied to one locale.Change. Delete the 36 retired keys from
pages.sessionStorageinko.jsonand addthe 29 inventory keys. One object in one file; no code, no English, no other locale.
The 36 removals are unreachable, not merely unused —
grep -rn "sessionStorage.<key>" website/srcreturns zero call sites for all 36. The only surviving matches on themove_to_trashstem are the two new keys atSessionStorageScreen.tsx:271and:478.Wording follows the terms already in
ko.jsonrather than a dictionary, perstyle/ko.md§2.2 "one concept, one word":세션 스토리지pages.performanceTab.session_storage— the screen that links here턴pages.sessionsTab.turns,pages.telemetryPanel.turns_col선택 해제issueRadar…prBulkBar.clear_selection오래된순pages.chatSidebar.sort_oldest회수headline_detail휴지통으로 이동fact_instanttrash_summaryandtrash_batch_reasonrecover their Korean from the retiredbatch_detail, which the redesign split into two keys — so that copy is thetranslator's own, not new.
Seven keys survived the redesign unchanged and are untouched, visible as context lines
in the diff.
Deliberately out of scope. #2298 also proposes running parity over every catalog on
disk rather than only
SUPPORTED_LANGUAGES, so a key migration fails in its own PRinstead of surfacing later as someone else's red build. That is a good change and a
separate one — it alters a shared gate's behaviour and could red other locales. Happy
to open it separately.
Tests
No new tests. This change exists to make existing gates pass, and those gates already
encode the invariant precisely:
catalogParity.test.ts— key-set parity, non-empty values, placeholder paritystyle/koStyle.test.ts— §1 punctuation, §1.1 Hangul-only, §2 의존명사 spacing +placeholder 조사 in both forms + fragment-initial 조사, §2.2 외래어 spellings, §4
register / 이중 피동 / label full stop, §5 plural categories
scripts/lib/qa-checks.mjsviacheck-source-strings.mjs— zero tolerance onchanged values
Adding a test here would only restate
catalogParity.Manual verification
vitest run src/i18n/catalogParity.test.tsonmainvitest run src/i18n/on this branchnode scripts/check-source-strings.mjs0 new key(s) vs origin/main, 0 finding(s);0 catalog QA finding(s) among values changednode scripts/i18n-check.mjsnpm run checkOne unrelated failure in the full run:
src/i18n/unitLiterals.test.tstimed out at15 s under
--coveragewith 8 workers. It passes in isolation in 2.7 s, and itexplicitly skips
locales/(lines 187 and 193), so it cannot see this diff. Samefamily as #2294 and #2301.
The diff was produced by a round-trip-verified rewrite:
json.dumps(…, ensure_ascii=False, indent=2) + "\n"reproduces the original file byte-for-bytebefore patching, so the diff contains only the 65 intended lines and no reformatting.
Screenshots / video
N/A — catalog-only diff. No component, layout, or theme changed; the rendered surface
is identical apart from the string values themselves.
Related Issues
Fixes #2298
Checklist
Contribution License Agreement