Skip to content

fix(i18n): resync ko Storage catalog with the inventory model - #2306

Merged
iamwhatever merged 1 commit into
kirodotdev:mainfrom
k33bz:fix/ko-storage-parity
Aug 9, 2026
Merged

iamwhatever merged 1 commit into
kirodotdev:mainfrom
k33bz:fix/ko-storage-parity

Conversation

@k33bz

@k33bz k33bz commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Problem / Motivation

catalogParity is red on main. The Korean catalog is desynced from en across the
whole Storage screen, so Frontend Tests fails for every open pull request that
touches website/:

FAIL src/i18n/catalogParity.test.ts > catalog parity > ko > has no key missing relative to en
  missing 29 key(s)
FAIL src/i18n/catalogParity.test.ts > catalog parity > ko > has no key absent from en
  36 stray key(s)

Reproduced on a pristine checkout of main: 2 failed | 75 passed (77).

Why it matters

Two layers, as #2298 sets out:

  1. Product — a Korean user on the Storage screen gets English for all 29 new
    strings, including the destructive-action explanations (cannot_delete_running,
    cannot_delete_resumable). Those are the strings you least want falling back to a
    language the user did not choose.
  2. CIcatalogParity runs inside Frontend Tests, so this reds an unrelated
    PR's Frontend TestsCoverage GatePR Readiness chain. Every author is
    currently 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.json was translated against the
bucket-based Storage screen, and the inventory-model redesign replaced that key set in
en.json without re-syncing Korean. The 36 strays are the retired bucket vocabulary
(bucket_7_30d, threshold_90d, batch_detail, …); the 29 missing are the inventory
vocabulary en gained. It is the rename half of a key migration applied to one locale.

Change. Delete the 36 retired keys from pages.sessionStorage in ko.json and add
the 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/src returns zero call sites for all 36. The only surviving matches on the
move_to_trash stem are the two new keys at SessionStorageScreen.tsx:271 and :478.

Wording follows the terms already in ko.json rather than a dictionary, per
style/ko.md §2.2 "one concept, one word":

Concept Rendering Precedent in this catalog
Session storage 세션 스토리지 pages.performanceTab.session_storage — the screen that links here
Turns pages.sessionsTab.turns, pages.telemetryPanel.turns_col
Clear (selection) 선택 해제 issueRadar…prBulkBar.clear_selection
Oldest first 오래된순 pages.chatSidebar.sort_oldest
reclaim 회수 the retired headline_detail
Move to Trash 휴지통으로 이동 the retired fact_instant

trash_summary and trash_batch_reason recover their Korean from the retired
batch_detail, which the redesign split into two keys — so that copy is the
translator'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 PR
instead 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 parity
  • style/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.mjs via check-source-strings.mjs — zero tolerance on
    changed values

Adding a test here would only restate catalogParity.

Manual verification

Check Result
vitest run src/i18n/catalogParity.test.ts on main 2 failed | 75 passed — bug reproduced
vitest run src/i18n/ on this branch 38 files, 597 passed
node scripts/check-source-strings.mjs 0 new key(s) vs origin/main, 0 finding(s); 0 catalog QA finding(s) among values changed
node scripts/i18n-check.mjs all sub-gates ok; 20 DNT terms intact across 11 catalogs
npm run check typecheck clean, lint 0 errors, 840 files / 11240 tests passed
dead-key grep for all 36 removals 0 call sites

One unrelated failure in the full run: src/i18n/unitLiterals.test.ts timed out at
15 s under --coverage with 8 workers. It passes in isolation in 2.7 s, and it
explicitly skips locales/ (lines 187 and 193), so it cannot see this diff. Same
family 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-byte
before 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

  • Single commit with a Conventional Commits title
  • Existing tests pass; no new tests (see Tests — the gates already encode this)
  • Self-review completed; code follows project style guidelines
  • Documentation updated (if applicable) — N/A, no documented behaviour changes
  • No secrets, credentials, or internal references in the diff

Contribution License Agreement

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
@k33bz
k33bz requested a review from a team as a code owner August 9, 2026 04:12
@github-actions github-actions Bot added fork Pull request from a fork (external contributor) readiness: action required A blocking check or review needs attention labels Aug 9, 2026
@github-actions github-actions Bot added readiness: checking Automated validation is still running and removed readiness: action required A blocking check or review needs attention labels Aug 9, 2026
@github-actions

github-actions Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

GPT 5.6 Review (fork) — ✅ no blocking findings

Reviewed 462e9f3fa4e301e706b4d96f636984bd0700888a via the fork AI-review pipeline; updated in place on each push.

Review details

No findings.
[GPT-REVIEWED] 462e9f3

@github-actions

github-actions Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Opus 5 Review (fork) — ✅ no blocking findings

Reviewed 462e9f3fa4e301e706b4d96f636984bd0700888a via the fork AI-review pipeline; updated in place on each push.

Review details

No findings.

[OPUS-REVIEWED] 462e9f3

@github-actions

github-actions Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Design Review (Fable 5, fork) — ✅ PASS

Advisory design-level review of 462e9f3fa4e301e706b4d96f636984bd0700888a via the fork AI-review pipeline — updated in place on each push; does not block merge.

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

@github-actions

github-actions Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

UX Review (Fable 5, fork) — ✅ PASS

Advisory UX-level review of 462e9f3fa4e301e706b4d96f636984bd0700888a via the fork AI-review pipeline — updated in place on each push; does not block merge.

All strings verified against en.json (36-key parity holds), consumption sites in SessionStorageScreen.tsx, and existing catalog precedent. One minor copy inconsistency found; otherwise the Korean strings read cleanly cold, destructive-path copy (cannot_delete_running, confirm_delete_forever) is accurate to the handlers, and terminology follows the catalog's established renderings.

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

  • Sort dropdown mixes spacing for the same suffix: "sort_largest": "큰 순" (spaced) sits beside "sort_oldest": "오래된순" (unspaced, matching chatSidebar.sort_oldest/sort_newest) in one SimpleSelect — align sort_largest to the catalog's unspaced convention.

[UX-REVIEWED] 462e9f3

@github-actions github-actions Bot added readiness: passed Eligible automated validation passed for the current revision and removed readiness: checking Automated validation is still running labels Aug 9, 2026
@iamwhatever
iamwhatever merged commit 841e8b4 into kirodotdev:main Aug 9, 2026
48 checks passed
@github-actions github-actions Bot removed the readiness: passed Eligible automated validation passed for the current revision label Aug 9, 2026
bolichen97 pushed a commit that referenced this pull request Aug 9, 2026
`**中文文本(带括号)。**这句子继续` 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.
bolichen97 added a commit that referenced this pull request Aug 9, 2026
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.
bolichen97 added a commit that referenced this pull request Aug 9, 2026
…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.
@k33bz
k33bz deleted the fix/ko-storage-parity branch August 14, 2026 21:37
encomjp pushed a commit to encomjp/kirocrew-customapi that referenced this pull request Aug 22, 2026
…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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

fork Pull request from a fork (external contributor)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

catalogParity red on main: ko.json still carries the retired bucket Storage keys and lacks the 29 inventory ones

2 participants