Skip to content

Commit b558570

Browse files
committed
Document the regular-string catalog fold in the localization pipeline
localization-pipeline.md described regular-string machine translation as deferred. The staging path now exists, so update that section: the regular-string catalog fold folds human translations into Localizable.xcstrings and AI-fills the gaps, the same shape as the plural fold, but manual (not in the release path) and not shipped (the catalog isn't the runtime store yet).
1 parent e795788 commit b558570

1 file changed

Lines changed: 10 additions & 5 deletions

File tree

docs/localization-pipeline.md

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,18 @@ The plural reverse-fold (`PluralStrings.fold_translations!`) fills each `(key, l
4545

4646
> **This does not ship machine translations yet.** `Plurals.xcstrings` is built into the app but **not consumed at runtime** — nothing reads the catalog, and nothing references its keys yet; the app still renders plurals the legacy way. The fold *pre-populates* the catalog so it's ready when plurals cut over to it. Until that cutover, the AI plural translations sit in the catalog unused.
4747
48-
## What's deferred: regular strings
48+
## What's staged, not shipped: regular strings
4949

50-
Regular (non-plural) strings are **not** machine-translated, by design. The app still ships the legacy `WordPress/Resources/<locale>.lproj/Localizable.strings` for them — `Localizable.xcstrings` (`generate_strings_catalog`) is the designated future backing store, but today it's only generated transiently in CI as a coverage check — the file is gitignored, not committed, and nothing ships from it. A machine translation written into the legacy `.strings` would be **live immediately**, and we don't want machine-translated regular strings shipping before the catalog cutover.
50+
Regular (non-plural) strings still ship the legacy way — from `WordPress/Resources/<locale>.lproj/Localizable.strings`, with no machine translation. A machine translation written there would be **live immediately**, and we don't want machine-translated regular strings shipping before the catalog cutover. `Localizable.xcstrings` (`generate_strings_catalog`) is the designated future backing store; it's gitignored and not a build member, so nothing ships from it.
5151

52-
So regular-string MT waits for the same shape as plurals: once `Localizable.xcstrings` becomes the runtime store, a regular-string **catalog reverse-fold** folds the human translations in and AI-fills the `needs_review` gaps, staged in the catalog (not shipped) until cutover — exactly as the plural fold does today.
52+
The tooling to **stage** regular-string translations into that catalog now exists, the same shape as the plural fold. `CatalogStrings.fold_translations!` fills each `(key, locale)` cell of `Localizable.xcstrings` as `human ?? AI ?? English` — human ⇒ `translated`, machine / English ⇒ `needs_review` — and is reuse-aware in the same way: a kept machine cell isn't re-translated, and a human translation supersedes it on the next fold. It runs as three manual lanes: `generate_strings_catalog` (extract the English source), `download_catalog_strings` (pull GlotPress into a gitignored scratch dir), and `localize_catalog` (fold the humans in, AI-fill the rest, commit the catalog).
5353

54-
When that's built, two facts established here will carry over:
54+
Two things keep it from shipping anything today, and both set it apart from the plural fold:
55+
56+
- **Manual, not in the release path.** These lanes aren't wired into `download_localized_strings` or any beta/release step — a run extracts strings, calls the API (cost), and commits a large catalog, so it's run on demand. Only the unit tests run in CI.
57+
- **Staged, not shipped.** `Localizable.xcstrings` still isn't the runtime store, so the folded translations sit in the catalog unused until the cutover — exactly like the plural catalog.
58+
59+
Two facts the fold relies on, both established by the reverse download:
5560

5661
- **"Undefined by GlotPress" = absent**, not empty. The export omits untranslated strings (`status: current`; verified no empty-valued entries), so absence is the untranslated signal.
5762
- **Humans always supersede MT**, and machine output never returns to GlotPress — so there's no translation-memory pollution and no manual reconciliation, as long as MT lives in a state-bearing store (the catalog's `needs_review`).
@@ -77,5 +82,5 @@ When that's built, two facts established here will carry over:
7782
| Brand do-not-translate + per-locale terms | `fastlane/lanes/translation_glossary.rb` |
7883
| Anthropic SDK glue + Message Batches | `fastlane/lanes/anthropic_batch.rb` |
7984
| Plural fold (`Localizable.strings``Plurals.xcstrings`) + AI wiring | `fastlane/lanes/plural_strings_helper.rb`, `fastlane/lanes/localization_plurals.rb` |
80-
| Catalog generation (future regular-string backing store) | `fastlane/lanes/localization_catalog.rb` |
85+
| Catalog generation + regular-string fold (staged, manual) | `fastlane/lanes/localization_catalog.rb`, `fastlane/lanes/catalog_strings_helper.rb` |
8186
| Download/upload orchestration | `fastlane/lanes/localization.rb` |

0 commit comments

Comments
 (0)